I have some python-2.x scripts which I copy between different systems, Debian and Arch linux. Debian install python as '/usr/bin/python' while Arch installs it as '/usr/bin/python2'. A problem is that on Arch linux '/usr/bin/python' also exists which refers to python-3.x. So every time I copy a file I have to correct the shebang line, which is a bit annoying.
On Arch I use
#!/usr/bin/env python2
While on debian I have
#!/usr/bin/env python
Since 'python2' does not exist on Debian, is there a way to pass a preferred application? Maybe with some shell expansion? I don't mind if it depends on '/bin/sh' existing for example. The following would be nice but don't work.
#!/usr/bin/env python2 python
#!/usr/bin/env python{2,}
#!/bin/sh python{2,}
#!/bin/sh -c python{2,}
The frustrating thing is that 'sh -c python{2,}' works on the command line: i.e. it calls python2 where available and otherwise python.
I would prefer not to make a make a link 'python2->python' on Debian because then if I give the script to someone else it will not run. Neither would I like to make 'python' point to python2 on Arch, since it breaks with updates.
Is there a clean way to do this without writing a wrapper?
I realize similar question have been asked before, but I didn't see any answers meeting my boundary conditions :) Conditional shebang line for different versions of Python
--- UPDATE
I hacked together an ugly shell solution, which does the job for now.
#!/bin/bash
pfound=false; v0=2; v1=6
for p in /{usr/,}bin/python*; do
v=($(python -V 2>&1 | cut -c 7- | sed 's/\./ /g'))
if [[ ${v[0]} -eq $v0 && ${v[1]} -eq $v1 ]]; then pfound=true; break; fi
done
if ! $pfound; then echo "no suitable python version (2.6.x) found."; exit 1; fi
$p - $* <<EOF
PYTHON SCRIPT GOES HERE
EOF
explanation: get version number (v is a bash array) and check
v=($(python -V 2>&1 | cut -c 7- | sed 's/\./ /g'))
if [[ ${v[0]} -eq $v0 && ${v[1]} -eq $v1 ]]; then pfound=true; break; fi
launch found program $p with input from stdin (-) and pass arguments ($*)
$p - $* <<EOF
...
EOF
Whether using the shebang for running scripts in Python is necessary or not, greatly depends on your way of executing scripts. The shebang decides if you'll be able to run the script as a standalone executable without typing the python command. So, if you want to invoke the script directly – use the shebang.
A shebang line #!/usr/bin/python3 Its purpose is to define the location of the interpreter. By adding the line #!/usr/bin/python3 on the top of the script, we can run the file.py on a Unix system and automatically will understand that this is a python script. Alternative, you could run the script as python3 file.py .
If you have installed many versions of Python, then #!/usr/bin/env ensures that the interpreter will use the first installed version on your environment's $PATH. If you are using Unix, an executable file that is meant to be interpreted can indicate what interpreter to use by having a #!
#!/usr/bin/env python """ The first line in this file is the "shebang" line. When you execute a file from the shell, the shell tries to run the file using the command specified on the shebang line. The ! is called the "bang". The # is not called the "she", so sometimes the "shebang" line is also called the "hashbang".
#!/bin/sh
''''which python2 >/dev/null 2>&1 && exec python2 "$0" "$@" # '''
''''which python >/dev/null 2>&1 && exec python "$0" "$@" # '''
''''exec echo "Error: I can't find python anywhere" # '''
import sys
print sys.argv
This is first run as a shell script. You can put almost any shell code in between ''''
and # '''
. Such code will be executed by the shell. Then, when python runs on the file, python will ignore the lines as they look like triple-quoted strings to python.
The shell script tests if the binary exists in the path with which python2 >/dev/null
and then executes it if so (with all arguments in the right place). For more on this, see Why does this snippet with a shebang #!/bin/sh and exec python inside 4 single quotes work?
Note: The line starts with four '
and their must be no space between the fourth '
and the start of the shell command (which
...)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With