10

How should the shebang for a Python script look like?

Some people support #!/usr/bin/env python because it can find the Python interpreter intelligently. Others support #!/usr/bin/python, because now in most GNU/Linux distributions python is the default program.

What are the benefits of the two variants?

Emil Vikström
  • 90,431
  • 16
  • 141
  • 175
Tanky Woo
  • 4,906
  • 9
  • 44
  • 75

4 Answers4

8

The Debian Python Policy states:

The preferred specification for the Python interpreter is /usr/bin/python or /usr/bin/pythonX.Y. This ensures that a Debian installation of python is used and all dependencies on additional python modules are met.

Maintainers should not override the Debian Python interpreter using /usr/bin/env python or /usr/bin/env pythonX.Y. This is not advisable as it bypasses Debian's dependency checking and makes the package vulnerable to incomplete local installations of python.

Note that Debian/Ubuntu use the alternatives system to manage which version /usr/bin/python actually points to. This has been working very nicely across a lot of python versions at least for me (and I've been using python from 2.3 to 2.7 now), with excellent transitions across updates.

Note that I've never used pip. I want automatic security upgrades, so I install all my python needs via aptitude. Using the official Debian/Ubuntu packages keep my system much cleaner than me messing around with the python installation myself.


Let me emphasize one thing. The above recommendation refers to system installation of python applications. It makes perfectly sense to have these use the system managed version of python. If you are actually playing around with your own, customized installation of python that is not managed by the operating system, using the env variant probably is the correct way of saying "use the user-preferred python", instead of hard-coding either the system python installation (which would be /usr/bin/python) or any user-custom path.

Using env python will cause your programs to behave differently if you call them from e.g. a python virtualenv.

This can be desired (e.g. you are writing a script to work only in your virtualenv). And it can be problematic (you write a tool for you, and expect it to work the same even within a virtualenv - it may suddenly fail because it is missing packages then).

Has QUIT--Anony-Mousse
  • 76,138
  • 12
  • 138
  • 194
  • 1
    But what happens when you want a package that isn't in the repos? Then you nee `pip`, or `easy_install`, or you need to suck it up and `python setup.py install` yourself... – mgilson Dec 14 '12 at 13:40
  • I never had that need. From my experience, anything that is good has already been packaged - and if it hasn't been packaged, it probably is broken in one way or another. Plus, we are talking about python, not python extension modules. You *can* use the python system installation and add custom modules, without having to do a full interpreter installation yourself. – Has QUIT--Anony-Mousse Dec 14 '12 at 13:42
  • 1
    I'm not sure what you mean. everybody's python is a little different because one of the things which makes python really useful is the various extensions you can use. Don't need `numpy`? No problem. If you need it, you need to obtain it one way or another. Need `spacepy`? I don't think it's in any repos anywhere, but I use it (and it's not broken AFAIK). I understand that you *can* add extensions to the system python. You can also choose to keep it as pristine as possible set up your own version for working in user-space. `/usr/bin/env` allows it to be a user decision. – mgilson Dec 14 '12 at 13:49
  • All the good python extensions *are* available as packages, and you *can* install extensions without reinstalling python yourself, i.e. without losing automatic security updates, and getting unpredictable behaviour because of `env` changes. – Has QUIT--Anony-Mousse Dec 14 '12 at 13:52
  • 2
    What I'm saying is that *not all good python extensions are available as packages* (one example -- `spacepy`). And *not all users have permissions to install extensions system-wide* and finally, *not all users are using Ubuntu/Debian* (`/usr/bin/python` fails on OS-X). If you use `/usr/bin/env`, the user can still use the system-wide python if they choose -- They just need to manage their environment properly (which they should be doing in any case). But again -- As I stated in my answer, it's really not a big deal either way. You can always try your script with any python installed. – mgilson Dec 14 '12 at 14:00
6

My humble opinion is that you should use the env-variant. It's a POSIX component thus found in pretty much every system, while directly specifying /usr/bin/python breaks in many occasions, i.e. virtualenv setups.

filmor
  • 30,840
  • 6
  • 50
  • 48
  • This is actually desired. Your virtualenv setup might be missing packages; it is not safe to assume that `env python` will yield the *intended* python installation. So a *shared* python program will suddenly fail if it is running in a different virtualenv as originally intended... to use a virtualenv, I recommend to always run your scripts as `python script.py` (but for scripts that are meant to only work in your virtualenv, the `env python` approach may be better; still it makes portability problematic). – Has QUIT--Anony-Mousse Apr 28 '17 at 15:39
  • Desired by whom? Using `env` here means that you will be using the Python that is right now resolved by `python something.py`. That's exactly what I want. If I wanted to use a different interpreter, I'd have switched environments. It's not a decision that I want a script author to take for me. It's an entirely different thing for your distribution's package maintainers, they should enforce the system interpreter. – filmor Apr 28 '17 at 16:12
4

I use #!/usr/bin/env python as the default install location on OS-X is NOT /usr/bin. This also applies to users who like to customize their environment -- /usr/local/bin is another common place where you might find a python distribution.

That said, it really doesn't matter too much. You can always test the script with whatever python version you want: /usr/bin/strange/path/python myscript.py. Also, when you install a script via setuptools, the shebang seems to get replaced by the sys.executable which installed that script -- I don't know about pip, but I would assume it behaves similarly.

mgilson
  • 300,191
  • 65
  • 633
  • 696
1

As you note, they probably both work on linux. However, if someone has installed a newer version of python for their own use, or some requirement makes people keep a particular version in /usr/bin, the env allows the caller to set up their environment so that a different version will be called through env.

Imagine someone trying to see if python 3 works with the scripts. They'll add the python3 interpreter first in their path, but want to keep the default on the system running on 2.x. With a hardcoded path that's not possible.

Paul Rubel
  • 26,632
  • 7
  • 60
  • 80
  • But with the `env` approach, system python programs will suddenly be run with his self-compiled python3, that he has somewhere in his path, and that might be lacking extensions. Random stuff will suddenly start failing. – Has QUIT--Anony-Mousse Dec 14 '12 at 13:38
  • That would be the point, to find out yourself before it fails for everyone else, without changing the files they maay need to run. – Paul Rubel Dec 14 '12 at 14:00
  • To test, use an explicit `test-python-installation/bin/python app.py`. – Has QUIT--Anony-Mousse Dec 14 '12 at 14:47
  • And hope that it doesn't directly or indirectly call any other python programs that use a hard-coded path. – Paul Rubel Dec 14 '12 at 15:32
  • Oh, exactly that may be desired. Just because it invokes another application *implemented* in python does not mean you will want it to use the same experimental python interpreter that you are currently messing with. You usually *do* want your system programs to behave as expected, by using the same interpreter as for any other user. In the worst case, they then suddenly no longer work at all, because your messy installation doesn't contain all their required packages. – Has QUIT--Anony-Mousse Dec 14 '12 at 15:34