17

I have a problem when trying to run a python script on two different computers. On each computer I would like to run the script using python version 2.7.3 however the problem I am having is that the two computers name python 2.7.3 in different ways. One of the computers runs arch linux and on this computer it is named python2. The other computer is running redhat linux and it uses the name python2.7.3.

What should I use in the shebang line so that the script is executable on both computers without requiring any changes? What I really want is some sort of conditional shebang line that could choose which version of Python to use. Am I just out of luck and I have to keep two different versions of the script?

P.S. I can't just use #!/usr/bin/env python as on the arch linux computer this would refer to python 3.2.3 and on the redhat linux computer it would refer to python 2.4.

martega
  • 2,103
  • 2
  • 21
  • 33
  • 4
    A magnificent question. Note that the recomended practice (according PEP-394), suggests that python2.x be symlinked as `python2`, so really this is sort of a packaging issue on redhat's behalf (amogst other distros). – WhyNotHugo Aug 22 '12 at 10:10
  • 2
    Why can't you define a new variable in each computer that will link to python2.7.3? or a just a link? – slallum Aug 22 '12 at 10:13
  • 2
    You can always go with `python2.7.3 my-program.py` :) – Shaung Aug 22 '12 at 10:46
  • 1
    I would use `#!/usr/bin/env python` or `#!/usr/bin/env python2` and guard version dependent code with explicit checks for the appropriate Python version (using [`sys.version_info`](http://docs.python.org/library/sys.html#sys.version_info)). Failing that then simlinks or @Shaung's solution is the easiest. – Chris Aug 22 '12 at 11:10

2 Answers2

11
#!/bin/sh
# -*- mode: Python -*-

""":"
# bash code here; finds a suitable python interpreter and execs this file.
# prefer unqualified "python" if suitable:
python -c 'import sys; sys.exit(not (0x020500b0 < sys.hexversion < 0x03000000))' 2>/dev/null \
    && exec python "$0" "$@"
for pyver in 2.6 2.7 2.5; do
    which python$pyver > /dev/null 2>&1 && exec python$pyver "$0" "$@"
done
echo "No appropriate python interpreter found." >&2
exit 1
":"""

import sys
print sys.version

taken from https://github.com/apache/cassandra/blob/trunk/bin/cqlsh

dhamu
  • 156
  • 1
  • 5
6

You can write a small wrapper script that looks through different versions of python executables and uses the one it finds.

For example:

#!/bin/sh -e
pythons=('python2', 'python2.7.3')
for py_exec in ${pythons[@]}; do
    py_exec="/usr/bin/$py_exec"
    if [[ -f $py_exec ]]; then
        exec $py_exec $1
    fi
done

Of course this script is just a start sample, you could surely improve it in many ways. Just do give you an idea of what I mean.

javex
  • 7,198
  • 7
  • 41
  • 60