0

What Python shebang should I use: #! /usr/bin/env python3 or #! /usr/bin/python3?

#! /usr/bin/python3:

  • Classical way.
  • Distributions without /usr/bin/ have a symlink
  • Same Python as you get on shell by python3
  • Distributions prefer it over /usr/bin/env for their packages (SuSE, Fedora)

#! /usr/bin/env python3:

  • Claimed to be more portable.
  • A lot of people (random ones from the internet) recommend it.

To make my question more precise: What should I use, when I want to write software and publish it on, e.g. GitHub, intending others to use and to package it.

usr1234567
  • 17,173
  • 10
  • 96
  • 112
  • What are you trying to acheive with either option? Preventing Python2 execution? Otherwise, is the script meant to be standalone rather than via `python3` command itself? – OneCricketeer Nov 13 '20 at 22:51
  • @OneCricketeer I want to keep the question open. I can image to have a standalone Python script, I can image to have a Python package consisting of multiple Python files, and I can image having a Java or C++ project that includes a Python file, as a helper tool or doing some task within the package. – usr1234567 Nov 13 '20 at 22:58

1 Answers1

3

Since you mentioned you will publish software on, e.g. GitHub, it doesn't actually matter what shebang you use. And you don't actually need to put a shebang at all.

When you publish a package for use by others, the installer (pip) will rewrite your shebangs at the time when the other person installs your package. This is because the contents or presence of a shebang is somewhat platform-dependent. On Windows, it won't put a shebang at all, and on linux/macOS it will hardcode the shebang to whichever Python executable was used to execute the installation.

See for example the shebang rewrite in stdlib distutils and also here in setuptools (setuptools is a monkeypatch on distutils, which is what pip will actually use these days).

Try it yourself, you can put #!potato into the source and then install the package in a virtualenv, potato will be gone and it will get rewritten to the venv's executable like #!/path/to/venv/bin/python.

wim
  • 266,989
  • 79
  • 484
  • 630
  • But people packaging my software have to change it to /usr/bin/python. – usr1234567 Nov 13 '20 at 22:54
  • 1
    No they don't. It's the installers job to write the shebang, not the packager. – wim Nov 13 '20 at 22:54
  • The RPM linter issues a warning that I shouldn't use /usr/bin/env! – usr1234567 Nov 13 '20 at 22:55
  • In the case of RPM packaging it's a little different than pip. But now you've said two different things here: are you creating and publishing an RPM, or are these other "people packaging my software" creating the RPM? – wim Nov 13 '20 at 23:02
  • I want to know, what's to prefer. One aspect of the question is, that people who package software shouldn't be forced to add patches for my shebangs. And yes, I tried to packages containing scripts and got the linter warnings myself. – usr1234567 Nov 13 '20 at 23:04
  • 1
    I'm repeating myself here, but you don't need to put shebangs in the source at all - that's what to prefer. For publishing PyPI packages, pip will (re)write them. For creating rpms, e.g. `python setup.py bdist_rpm` will (re)write them. If you use `fpm`, then fpm will write them. So it's probably best you just leave them out. – wim Nov 13 '20 at 23:07
  • 1
    Think about it: only the user can say where they have actually installed Python on their own machine, and maybe they even have multiple installations. It's not for you to say. So you *can't* write a shebang which is going to work for everybody. That part has to be decided or handled by the user's own operating system, at their end. – wim Nov 13 '20 at 23:16
  • I like the thougt! But isn't that the reason we have a symlink /usr/bin/python3 and /usr/bin/env for, to let the user define what she wants? – usr1234567 Nov 14 '20 at 06:16