No-shebang Python

Python's shebang tradition is particularly egregious. For many years, the conventional wisdom has been that you can't be certain where the Python interpreter is installed, but I guess you can be certain it's somewhere in your PATH, so you should rely on the POSIX env utility to locate it, like so:

#!/usr/bin/env python

Of course, the problem is, even on systems that do support shebangs, there's no guarantee that env is in /usr/bin.

Fortunately, Python provides the -x option, which skips the first line of the source file. This is listed in help as supporting "non-Unix forms of #!cmd", but it works equally well on POSIX platforms (this works for both Python 2 and Python 3):

exec python -x $0 "${1+$@}"

The unfortunate thing about this method, though, is that it doesn't allow you to run your script with the interpreter:

$ cat hello.py
exec python -x $0 "${1+$@}"

print("hello, python")
$ python hello.py
  File "hello.py", line 1
    exec python -x $0 "${1+$@}"
                   ^
SyntaxError: invalid syntax

There is a workaround, though. Using a combination of Python docstrings and sh quoting, we arrive at this combination (again, works with Python 2 and Python 3):

''''exec python -x $0 "${1+$@}"
' '''

This opens a Python docstring, closes the sh quote, executes the script with Python, and closes the docstring. So a no-shebang "Hello world" in Python comes out looking like this:

$ cat hello.py
''''exec python -x $0 "${1+$@}"
' '''

print("hello, python")
$ sh ./hello.py
hello, python
$ python2 ./hello.py
hello, python
$ python3 ./hello.py
hello, python
$ chmod +x hello.py
$ ./hello.py
hello, python
Copyright © 2019 Jakob Kaivo <jakob@kaivo.net>