#!/usr/bin/env bash
Instead of: #!/bin/bash
This makes the script more portable as you don't rely on bash (or any executable) to be in /bin. #!/usr/bin/env bash
Instead of: #!/bin/bash
This makes the script more portable as you don't rely on bash (or any executable) to be in /bin.The other thing is, if you're targeting obscure systems, wouldn't it be just as likely that there wouldn't be a /usr/bin/env, /usr/ might not be mounted, or that bash might not be installed at all?
I suppose what I'm asking is: for practical purposes, is the lowest common denominator /usr/bin/env or is it /bin/sh?
I don't use env on my shebang lines specifically because it's then PATH ordering dependent (there used to be a thing where /usr/local/bin and GNU tools were last in root's path, but first in non-root users' path). I'm more confident (perhaps incorrectly) that /bin/bash or /usr/local/bin/bash is what I expect it is vs the first thing found in PATH that is named bash is what I think it is (however, this applies moreso to coreutils-like things, that have different SysV vs BSD semantics/options, vs a shell such as bash, which is known everywhere to be GNU bash). Some tools, like ssh, can propagate environment settings based on local, remote or config file settings, and I'd rather not be surprised.
This used to be a bigger deal on systems that put reasonable (where "reasonable" == "what you're used to") tools in /usr/ucb or /opt/gnu, rather than system paths. If you're going to create something that's intended to be "portable", you've got bigger fish to fry than if and where bash is available, and it's wise to abstract system differences to different scripts (run.linux.sh, run.freebsd.sh, run.osx.sh, run.aix.sh, etc) than try to keep everything in one massive script anyway.
FreeBSD = /usr/local/bin/bash
OpenBSD = /usr/local/bin/bashYes there are.
OpenBSD for instance installs third party software under /usr/local. Bash is not a part of the base system.
env(1) on the other hand is a POSIX standard utility and comes with the OS.
Usually Solaris would get GNU tools installed beneath /opt, or similar, rather than in /bin.
#!/bin/sh
if [ -z "$BASH_VERSION" ]; then
if which bash >/dev/null 2>/dev/null; then
exec bash "$0"
else
echo "ERROR: bash was not in your PATH" >&2
exit 1
fi
fi
# now start using bash-only shortcuts safely
if [[ "hello" == "hello" ]]; then
echo Bash has been achieved.
fi
I'm not promising that's completely foolproof (it clearly isn't), but it works with the default Ubuntu 13.10 config of having /bin/sh linked to /bin/dash. And you could easily expand on the idea to look in specific locations for the bash binary even if it's not in the path, check those binary's versions, etc.Those sort of deployments got a lot of milage out of /usr/bin/env
https://en.wikipedia.org/wiki/Unix_directory_structure#Conve...
Not that this rule of thumb helps define the location of bash. It may or may not be considered essential for recovery.
[1] https://en.wikipedia.org/wiki/Filesystem_Hierarchy_Standard http://www.linuxfoundation.org/collaborate/workgroups/lsb/fh...
Basically everything that isn't a typical gnu/linux distro or osx. Bash is not a standard tool, it is a gnu specific shell. Posix requires env to exist, and requires it to exist in /usr/bin/. If you are using bashisms, then using /usr/bin/env bash will let people without bash see that your script is a bash script, and install bash to solve the problem. If you hardcode /bin/bash they have to fix your script.
> is the lowest common denominator /usr/bin/env or is it /bin/sh
Ideally you should use /bin/sh of course. But it is missing functionality some people want to use, so in that case using bash the portable way is preferred over using bash the unportable way.