Annoyingly, that also changes the file type for file
. It’s not env
-aware.
POSIX in fact reccomends that you change your script’s shebang for every system you install it on:
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
On some implementations this might return:
/usr/xpg4/bin/sh
Furthermore, on systems that support executable scripts (the “#!” construct), it is recommended that applications using executable scripts install them using getconf -v to determine the shell pathname and update the “#!” script appropriately as it is being installed (for example, with sed).
Which is contrary to the myth that’s often repeated when this comes up that /bin/sh
is fine because sh is mandated to be available according to POSIX. Though /bin/sh
will actually work on NixOS.
That means strictly, the “correct” fix is to install the scripts using buildShellApplication
, writeShellScriptBin
or a stdenv.mkDerivation
, as all of those will replace the shebang.
Alternatively you can also symlink /bin/bash
into place, of course… Here’s the development discussion on that: Add /bin/bash to avoid unnecessary pain - #3 by bhipple
To explain the argument of “purity” a bit better, the fear is that, if a package executes /bin/bash
accidentally at build time, this could result in build failures due to bash version changes. Since nix doesn’t sandbox the build env on all supported platforms this is a real concern. That said, NixOS does sandbox the build env, and if you install nix on other platforms this can’t be prevented anyway, so maybe it’s a moot point nowadays?