Shebang Notation: Python Scripts on Windows and Linux

Proper shebang of python script running on Windows

The interpretation of the shebang lines on Linux (and Unix like machines) is done by the operating system, and Windows doesn't do that, so there is no proper shebang line.

So if you don't want to do something special like selecting a particular Python version for your program, you can leave out the shebang (or leave in the one you need for running on Linux).

If your .py files are registered on Windows to be started by a particular Python executable, it is possible to check the first line of that file and interpret it to make sure you start the right version.

It is possible to start another Python version in that way with the original file and other arguments, but keep in mind that if you use that to start e.g a Python 2.7 interpreter where Python 3.8 is the one registered, that your Python program must be valid Python for both versions (so no print statements, f'{somevar}' strings, etc.)

python scripts with shebang for Windows

Not sure if I understood your question correctly, but I guess you want to run the command 'nfile' from anywhere in Windows command line.

This is possible with the help of another batch (.bat) file. You need create a file called 'nfile.bat' next to the script.
Both the script and batch file need to be in a location that's defined in PATH.

The content of the batch file should contain something like:

python nfile.py

Should I put #! (shebang) in Python scripts, and what form should it take?

The shebang line in any script determines the script's ability to be executed like a standalone executable without typing python beforehand in the terminal or when double clicking it in a file manager (when configured properly). It isn't necessary but generally put there so when someone sees the file opened in an editor, they immediately know what they're looking at. However, which shebang line you use is important.

Correct usage for (defaults to version 3.latest) Python 3 scripts is:

#!/usr/bin/env python3

Correct usage for (defaults to version 2.latest) Python 2 scripts is:

#!/usr/bin/env python2

The following should not be used (except for the rare case that you are writing code which is compatible with both Python 2.x and 3.x):

#!/usr/bin/env python

The reason for these recommendations, given in PEP 394, is that python can refer either to python2 or python3 on different systems.

Also, do not use:

#!/usr/local/bin/python

"python may be installed at /usr/bin/python or /bin/python in those
cases, the above #! will fail."

―"#!/usr/bin/env python" vs "#!/usr/local/bin/python"

Shebang in windows

Most language runtimes that run across platforms know about the shebang and ignore it, regardless of platform, or (as in the case of Perl), known about it and do the right thing with it (by invoking the desired program). So if you're using a language like PHP which runs across a variety of OSes, then you should have no problems.

In addition, many of these languages ignore the shebang because in that language the hash mark (#) starts a comment, so even if they lack special handling for it, they'll ignore it nevertheless.

The only time you might ever see a problem with a script is if you have a language where # is not a comment and it runs only on Windows, but I know of very few languages where that's the case.

interchangeable shebang line in Python script for dual OSes?

If you don't mind adding extra steps, ou can create a launcher script launcher.py like:

#!/usr/bin/env python

import subprocess
import sys

if __name__ != "__main__":
print("This is a launcher. Please run only as a main script.")
exit(-1)

INTERPRETERS = {
"win": r"C:\Users\windows-username\Envs\some_env\Scripts\python.exe", # Windows
"darwin": "/Users/os-x-username/.virtualenvs/some_env/bin/python", # OSX
"linux": "/home/linux-user/.virtualenvs/some_env/bin/python" # Linux
# etc.
}

TARGET_SCRIPT = "original_script_name.py"

interpreter = None
for i in INTERPRETERS: # let's find a suitable interpreter for the current platform
if sys.platform.startswith(i):
interpreter = i
break
if not interpreter:
print("No suitable interpreter found for platform:", sys.platform)
exit(-1)

main_proc = subprocess.Popen([interpreter, TARGET_SCRIPT] + sys.argv[1:]) # call virtualenv
main_proc.communicate() # wait for it to finish

exit(main_proc.poll()) # redirect the return code

Since this script is there only to run the original_script_name.py in the desired interpreter for the current platform, it doesn't matter what its shebang is - as long as it picks any Python interpreter it will be fine.

It would act as a drop-in replacement for your original script (original_script_name.py) so just call launcher.py instead and it will even redirect the CLI arguments if needed.

using #!/usr/bin/env python3 shebang with Windows

No, Windows does not support shebang lines.

The documentation you've linked relates to the py launcher installed by Python, which can interpret various shebang lines to choose a Python version to run a script with.

setuptools is able to generate wrapper .exes for your Python scripts, but it gets a little involved and already assumes you have a package with a setup.py and so on.

Locally, if you really, really need this, you probably could add .py to the PATHEXT environment variable, so the Windows command line looks up .pys like it looks up .exes (and various others; the current modern default is .COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH;.MSC). However, this will naturally not scale for distributing apps, as all of your users would need to set that too.

My recommendation is to stick with just that boring old python testing.py, really.

Is it possible to construct a shebang that works for both Python 2 and 3?

Realistically I would just specify python3 and make that a prerequisite.

However, it's technically possible to trick a Python file into being its own shell script wrapper:

#!/bin/sh
''':'
for name in python3 python2 python
do
type "$name" > /dev/null 2>&1 && exec "$name" "$0" "$@"
done
echo >&2 "Please install python"
exit 1
':'''

print("Hello from Python")


Related Topics



Leave a reply



Submit