5 ms·
I really don't like the `/usr/bin/env bash` approach (it came from the ruby world I think?). It's less portable than /bin/bash in my experience - I've been in e
by nvarsj 8y ago
I really don't like the `/usr/bin/env bash` approach (it came from the ruby world I think?). It's less portable than /bin/bash in my experience - I've been in environments, usually older ones, where it doesn't work at all. But /bin/bash works everywhere. You also can't pass command line arguments. And it's slightly more complex than just invoking /bin/bash.
- davidcuddeback 8y ago> It's less portable than /bin/bash in my experience /bin/bash breaks on FreeBSD, which installs Bash at /usr/local/bin/bash. /usr/bin/env bash works though. > You also can't pass command line arguments. Are you sure about that? Given this script: #!/usr/bin/env bash echo "args: $@" it outputs: $ ./foo 1 2 3 args: 1 2 3 Is that what you meant?
- nvarsj 8y agoYou can do “/bin/bash -e” but not “/usr/bin/env bash -e”. Same for python etc. Good point about freebsd - I remember running into that exact problem. But I think I just symlinked it. https://unix.stackexchange.com/questions/29608/why-is-it-better-to-use-usr-bin-env-name-instead-of-path-to-name-as-my/29620#29620 https://unix.stackexchange.com/questions/29608/why-is-it-bet... has more info on the pitfalls. In my experience env causes problems, whereas explicit binary call always works (assuming the path exists). Not sure why I was downvoted.
- jessaustin 8y agoIs this a problem with env? What does the "-e" flag do anyway? "man bash" proved unenlightening.
- jolmg 8y agoIt's not because of env. It's just that shebangs are limited to passing one optional argument to the executable specified. The way they're parsed is the executable path, and if there's a space, then the rest of the line (including any additional spaces) is interpreted as 1 argument to the executable. EDIT: -e causes bash to exit on the first command that returns with an error (returns with a non-zero return code). It's documented in `man bash` where it documents the `set` builtin command.
- jessaustin 8y agoThanks for clarifying. In that case, one could imagine an env capable of parsing its single argument into the multiple intended arguments? I admit that I never dreamed that the "set" builtin would have the information about "bash -e" while the initial "OPTIONS" section did not. Why not look under the "cd", "echo", "fc", "read", or "ulimit" builtins? Somewhat helpfully, the "COMMAND EXECUTION ENVIRONMENT" section talks about how "-e" is inherited but not what it means. Ah, man pages.
- jolmg 8y agoWell, to be fair, the first sentence in OPTIONS is: > All of the single-character shell options documented in the description of the set builtin command can be used as options when the shell is invoked. It's easy to miss though, when one's accustomed to quickly searching with "/". EDIT: On the imagined env, it might be possible. I wonder what aspects of shebangs are portable across the various unix derived OSs. It may be that there's some systems where it only takes non-whitespace characters as the first argument and drops everything else after encountering another space. There might be also other limitations that one should consider when making more use of shebangs, like the character limit of the lines. For example, I think linux only takes the first 127 characters of the shebang and ignores everything else; other systems might take less. I encountered that limit when writing this answer: https://unix.stackexchange.com/questions/365436/choose-interpreter-after-script-start-e-g-if-else-inside-hashbang/365751#365751 https://unix.stackexchange.com/questions/365436/choose-inter... EDIT 2: If you were to do such a program, it will probably also need to implement quoting and escaping syntax. The difficult part is that, since it wouldn't be a standard program to have, it'd have to be listed as a dependency of whatever projects you use it in, and I wonder if the benefit really outweighs the cost of having yet another dependency. I can't see something like this gaining wide adoption.
- jessaustin 8y agoHaha thanks that is why I missed it.
- JdeBP 8y ago
- davidcuddeback 8y ago> You can do “/bin/bash -e” but not “/usr/bin/env bash -e”. Makes sense. Thanks for clarifying. I had a feeling I wasn't understanding your point.
- jolmg 8y agoHe probably means you can't: #!/usr/bin/env bash -ex but you can: #!/bin/bash -ex
- davidcuddeback 8y agoAh, makes sense then. Thanks for clarifying.
- deleted 8y ago[deleted]
- mitchty 8y ago> I really don't like the `/usr/bin/env bash` approach (it came from the ruby world I think?). It's less portable than /bin/bash in my experience - I've been in environments, usually older ones, where it doesn't work at all. Its not a ruby thing, its the way you're supposed to write portable scripts where the location of the executable might not be predetermined. Lets say you're on a distribution where bash is in /usr/bin/bash instead of /bin/bash. Well you'll be modifying the shebang line to either do /usr/bin/env bash or pointing it to that spot. What old systems didn't it work on? I've used everything from SunOS, Irix, HPUX, AiX, Solaris, Linux, bsd's, anything claiming to be posix has to support that.
- deleted 8y ago[deleted]
- h1d 8y agoFunny that if env is such a crucial part of the OS, why isn't it in /bin?
- tomc1985 8y ago/usr/bin/env anything is a pain to use with cronjobs
- jolmg 8y agoI don't have much experience with cronjobs, but is $PATH not set-up properly in their environment?
- tomc1985 8y agoI don't remember exactly but it may be $PATH. I run into this trying to run rvm-managed Ruby scripts in cronjobs. The solution (IIRC) is to explicitly reference the interpreter you want to run in the cronjob line.
- jolmg 8y agoIt didn't work because there was no /usr/bin/env in these systems, or because you wanted a bash different from what was found with $PATH to execute? What were these systems?
- nvarsj 8y agoI think many lightweight container images don’t have /usr/bin/env for example but they all have /bin/sh. Which I think is the best option for portability. /usr/bin/env is not POSIX anymore than /bin/bash etc.
- ithkuil 8y agohttp://manpag.es/RHEL6/1p+env http://manpag.es/RHEL6/1p+env Mentions that the env command is POSIX, but it doesn't mention the absolute path. Are you saying that /use/bin/env is not POSIX because there is no guarantee that it will be available at that particular path?
- jolmg 8y agoInterestingly enough, not even the path of /bin/sh is guarenteed. From the POSIX: > Applications should note that the standard PATH to the shell cannot be assumed to be either /bin/sh or /usr/bin/sh, and should be determined by interrogation of the PATH returned by getconf PATH, ensuring that the returned pathname is an absolute pathname and not a shell built-in. EDIT: I wondered what POSIX recommended to do for any use of the shebang and this is what I found: > Furthermore, on systems that support executable scripts (the "#!" construct), it is recommended that applications using executable scripts install them using getconf PATH to determine the shell pathname and update the "#!" script appropriately as it is being installed (for example, with sed). Wow.