What is the recommended POSIX sh shebang
Formal perspective
The informative section of the POSIX specification for
sh: Application Usage states
that you cannot rely on the sh
executable being installed at /bin/sh
.
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.
For example, to determine the location of the standard sh utility:
command -v sh
However, instead of suggesting the use of env
to use the appropriate PATH,
it suggests that shell scripts should be modified at installation time to use
the full path to sh
:
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).
In practice
I mostly write POSIX shell scripts and, in practice, every GNU/Linux system
(Red Hat and Debian-based) – and others such as Cygwin and OS X – has a
POSIX-compliant sh
either installed to /bin/sh
or available as a soft or
hard link at this path. I’ve never needed to use env
to cater for systems
where sh
does not use this path.
There may be some Unix systems where a POSIX-compliant sh
is not available
as /bin/sh
. The POSIX specification suggests that it might be installed on
some systems as /usr/xpg4/bin/sh
. As I understand it, this is (was?) true
for Solaris systems where /bin/sh
is an earlier version of the Bourne shell
which predates POSIX. In this case, using env sh
would not be guaranteed to help as it could still find the Bourne shell (at /bin/sh
) before the POSIX shell at /usr/xpg4/bin/sh
.
Summary
If you’re writing POSIX shell scripts for common Unix and Linux operating
systems, simply use #!/bin/sh
as the shebang.
In rare cases where /bin/sh
is a Bourne shell instead of a POSIX-compliant
shell, you would have to modify the shebang to use the appropriate full path
to the POSIX shell.
In either case, there’s no benefit to using #!/usr/bin/env sh
– and would be
more likely to fail than simply using #!/bin/sh
.