Scripting – Guarantee of /usr/bin/env Existence

envscripting

Often I will see scripts begin with a shebang line that uses #!/usr/bin/env interpreter_name for whatever interpreter, with the rationale that different systems might have the interpreter that they need in order to run installed in different places. For instance, if I assume python is installed as /usr/bin/python then some user who decided to install it as /opt/python for some reason won't be able to use it as easily.

But the obvious question is, is there any guarantee that env will be installed at /usr/bin/env (or for that matter any particular place), or is this just a case of "moving the problem" so to speak?

This slightly related question has a comment that says it's a bad idea and it's preferable to install it with the actual path of the interpreter and cites the single unix specification but does not really address this question.

Best Answer

No, env is not guaranteed to be in /usr/bin, as you can read in the history of the shebang mechanism, in the section "The env utility":

However, the location of env(1) might vary. Free-, Net-, OpenBSD and some Linux distributions (e.g. Debian) only come with /usr/bin/env. On the other hand, there's only /bin/env at least on SCO OpenServer 5.0.6 and Cray Unicos 9.0.2 (although the latter is only of historical interest). On some other Linux distributions (Redhat) it's located in /bin and /usr/bin/ contains a symbolic link pointing to it.

It does not move the problem completely, because of the flexibility of env searching $PATH. If you happen to get some scripts that use a different location for env from yours, you only have to know about where your env lives, and not also where perl, python, and other interpreters might be installed.

And you don't have to hard code /opt/python/3.3.2/bin/python3.3 if that is the first python3.3 executable in your PATH. You can just rely on env finding it, so you don't have to update each and every script if you upgrade to use /opt/python/3.3.3/bin/python3.3. You script header stays the same:

#! /usr/bin/env python3.3
Related Question