See also my Stack Exchange answer on the advantages and disadvantages of the "#!/usr/bin/env ..." convention: https://unix.stackexchange.com/a/29620/10454
Quick summary: The advantage of "#!/usr/bin/env INTERP" is that it will use the first INTERP in the user's $PATH. The disadvantage is that it will use the first INTERP in the user's $PATH.
You would be correct about that. And that sucks.
If I am writing a script that needs to be that portable, then I'll use #!/usr/bin/env sh but otherwise /bin/sh will work in all the cases I need it to.
Since bash's path might vary more, I might consider calling env to locate it then more often.
I believe that in Solaris before Solaris 10, /bin/sh was the original Bourne shell (which didn't comply with POSIX), and in Solaris 10 it's ksh (which isn't either, but is way closer): https://unix.stackexchange.com/questions/538844/does-posix-g...
Also, I don't think that "#!" is specified in POSIX. It's extremely common, it's just not in the specification. This is similar to find's "-print0" option, which also isn't in the POSIX specification but basically everyone implements it.
If you want a specification of "where things go", the closest one in practice (and one that most modern distributions try to follow) is the Filesystem Hierarchy Standard (FHS): https://refspecs.linuxfoundation.org/FHS_3.0/fhs/index.html
POSIX specifically calls out that it doesn't guarantee that the path is "/bin/sh":
107271 Applications should note that the standard PATH to the shell cannot be assumed to be either
107272 /bin/sh or /usr/bin/sh, and should be determined by interrogation of the PATH returned by
107273 getconf PATH, ensuring that the returned pathname is an absolute pathname and not a shell
107274 built-in.
https://pubs.opengroup.org/onlinepubs/9699919799/utilities/s...POSIX mentions "#!" several times, but doesn't require it; saying things like "on systems that support executable scripts (the "#!" construct)".
As the lack of a hard-codable path is frustrating, it recommends setting the shebang at install-time:
107279 Furthermore, on systems that support executable scripts (the "#!" construct), it is
107280 recommended that applications using executable scripts install them using getconf PATH to
107281 determine the shell pathname and update the "#!" script appropriately as it is being installed
107282 (for example, with sed). For example:For example, on my (Mac) laptop, /bin/bash is bash 3.2.57 (released in 2007), while "/usr/bin/env bash" gets the version installed by homebrew which is 4.4.19 (released in 2016).
Another fun fact is that execve() (which executes shebangs) only allows a single argument to the shebang program. Meaning if you use '#!/usr/bin/env sh', you can't specify arguments to 'sh' in the shebang. In any case, the name of the file being executed is appended as an additional argument at the end of the shebang.