What is the preferred Bash shebang?
I recommend using:
#!/bin/bash
It's not 100% portable (some systems place bash
in a location other than /bin
), but the fact that a lot of existing scripts use #!/bin/bash
pressures various operating systems to make /bin/bash
at least a symlink to the main location.
The alternative of:
#!/usr/bin/env bash
has been suggested -- but there's no guarantee that the env
command is in /usr/bin
(and I've used systems where it isn't). Furthermore, this form will use the first instance of bash
in the current users $PATH
, which might not be a suitable version of the bash shell.
(But /usr/bin/env
should work on any reasonably modern system, either because env
is in /usr/bin
or because the system does something to make it work. The system I referred to above was SunOS 4, which I probably haven't used in about 25 years.)
If you need a script to run on a system that doesn't have /bin/bash
, you can modify the script to point to the correct location (that's admittedly inconvenient).
I've discussed the tradeoffs in greater depth in my answer to this question.
A somewhat obscure update: One system I use, Termux, a desktop-Linux-like layer that runs under Android, doesn't have /bin/bash
(bash
is /data/data/com.termux/files/usr/bin/bash
) -- but it has special handling to support #!/bin/bash
.
Using a shebang line to invoke the appropriate interpreter is not just for BASH. You can use the shebang for any interpreted language on your system such as Perl, Python, PHP (CLI) and many others. By the way, the shebang
#!/bin/sh -
(it can also be two dashes, i.e. --
) ends bash options everything after will be treated as filenames and arguments.
Using the env
command makes your script portable and allows you to setup custom environments for your script hence portable scripts should use
#!/usr/bin/env bash
Or for whatever the language such as for Perl
#!/usr/bin/env perl
Be sure to look at the man
pages for bash
:
man bash
and env
:
man env
Note: On Debian and Debian-based systems, like Ubuntu, sh
is linked to dash
not bash
. As all system scripts use sh
. This allows bash to grow and the system to stay stable, according to Debian.
Also, to keep invocation *nix like I never use file extensions on shebang invoked scripts, as you cannot omit the extension on invocation on executables as you can on Windows. The file command can identify it as a script.
You should use #!/usr/bin/env bash
for portability: different *nixes put bash
in different places, and using /usr/bin/env
is a workaround to run the first bash
found on the PATH
. And sh
is not bash
.
/bin/sh
is usually a link to the system's default shell, which is often bash
but on, e.g., Debian systems is the lighter weight dash
. Either way, the original Bourne shell is sh
, so if your script uses some bash
(2nd generation, "Bourne Again sh") specific features ([[ ]]
tests, arrays, various sugary things, etc.), then you should be more specific and use the later. This way, on systems where bash is not installed, your script won't run. I understand there may be an exciting trilogy of films about this evolution...but that could be hearsay.
Also note that when evoked as sh
, bash
to some extent behaves as POSIX standard sh
(see also the GNU docs about this).