You need to run a bash script on several machines, but bash is not always in the same place. See Getting bash for xBSD.
Use the /usr/bin/env command in the shebang line, as in #!/usr/bin/env bash
. If your system doesn’t
have env in /usr/bin, ask your
system administrator to install it, move it, or create a symbolic link
because this is the required location. For example, Red Hat inexplicably uses /bin/env,
but they at least create a symlink to the correct location.
You could also create symbolic links for bash itself, but using env is the canonical and correct solution.
env’s purpose is to “run a program in a modified environment,” but since it will search the path for the command it is given to run, it works very well for this use.
You may be tempted to use #!/bin/sh
instead.
Don’t. If you are using bash-specific features in
your script, they will not work on machines that do not use
bash in Bourne shell mode for
/bin/sh (e.g., BSD, Solaris, Ubuntu 6.10+). And even if you aren’t using
bash-specific features now, you may forget about
that in the future. If you are committed to using only POSIX features, by all means use #!/bin/sh
(and don’t develop on Linux, see
Developing Portable Shell Scripts), but otherwise be
specific.
You may sometimes see a space between #!
and /bin/whatever
. Historically there were some
systems that required the space, though in practice we haven’t seen one
in a long time. It’s very unlikely any system running
bash will require the space, and the lack of the
space seems to be the most common usage now. But for the utmost
historical compatibility, use the space.
We have chosen to use #!/usr/bin/env
bash
in the longer scripts and functions we’ve made available
to download (see the end of the Preface for details), because that will
run unchanged on most systems. However, since env
uses the $PATH
to find
bash, this is arguably a security issue (see Avoiding Interpreter Spoofing), albeit a minor one in our
opinion.
Ironically, since we’re trying to use env
for portability, shebang line processing is not consistent across
systems. Many, including Linux, allow only a single argument to the
interpreter. Thus #!/usr/bin/env
bash
-will result in the error:
/usr/bin/env: bash -: No such file or directory
This is because the interpreter is /usr/bin/env
and the single allowed argument
is bash -. Other systems, such as BSD and
Solaris, don’t have this restriction.
Since the trailing -is a common security practice (see Avoiding Interpreter Spoofing) and since this is supported on some systems but not others, this is a security and portability problem.
You can use the trailing -for a tiny bit more security at a cost of portability, or omit it for portability at a cost of a tiny potential security risk. Since env is searching the path anyway, using it should probably be avoided if you have security concerns; thus the inability to portably use the trailing -is tolerable.
Therefore, our advice is to omit the trailing - when using env for portability, and to hard-code the interpreter and trailing - when security is critical.
The following web pages for information on shebang (/usr/bin/env):
—http://srfi.schemers.org/srfi-22/mail-archive/msg00069.html |
—http://www.in-ulm.de/~mascheck/various/shebang/ |
—http://homepages.cwi.nl/~aeb/std/hashexclam-1.html |
—http://www.faqs.org/faqs/unix-faq/faq/part3/, section 3.16: Why do some scripts start with #! … ? |
3.15.219.217