Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Robust Python3 shebang line?

Is there a way to write the shebang line such that it will find the Python3 interpreter, if present?

Naively, from PEP 394 I would expect that #!/usr/bin/env python3 should work.

However, I've noticed that on some systems where python is Python3, they don't provide a python3 alias. On these systems, you'd need to use #!/usr/bin/env python to get Python3.

Is there a robust way to handle this ambiguity? Is there some way to write the shebang line such that it will use python3 if present, but try python if not? (Requiring that end users manually fix their systems to add a python3 alias is not ideal.)

like image 481
R.M. Avatar asked Jun 21 '19 18:06

R.M.


1 Answers

The only way I can see to do this is to provide your own shebang wrapper to call the correct version of python. If you can reliably place the wrapper in a set location you can do this:

Create wrapper script, e.g. /usr/local/bin/python3_wrapper

#!/bin/bash
cmd="$1"
shift
if which python3 >/dev/null; then
  exec python3 "$cmd" "$@"
elif which python >/dev/null; then
  version=$(python --version 2>&1 | cut -d' ' -f2 | cut -d. -f1)
  if [[ "$version" == "3" ]]; then
    exec python "$cmd" "$@"
  else
    echo "python is version $version (python3 not found)"
  fi
else
  echo "python3 nor python found"
fi
exit 1

Then use the following shebang in your script:

#!/usr/local/bin/python3_wrapper

Your other option would be to call a python script that works in both version 2 and 3 that then calls your python3 script using the correct executable. If your script is called script.py then rename it to script.py3 and create script.py as follows:

#!/usr/bin/env python

import os
import sys

if sys.version_info.major == 3:
    exe = "python"    # python is version 3.x
else:
    exe = "python3"   # python is not version 3.x so try python3
try:
    os.execvp(exe, [exe, sys.argv[0]+'3'] + sys.argv[1:])
except:
    print(exe, "not found")
sys.exit(1)
like image 165
Dale Wilson Avatar answered Oct 25 '22 20:10

Dale Wilson