Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

I need to write a Python script that's compatible with both Python 2 and Python 3, can be called directly from a shell (meaning it has a shebang), and can run on systems that have either Python version installed, but possibly not both.

Normally I can write a shebang for Python 2 like so:

#!/usr/bin/env python

and for Python 3:

#!/usr/bin/env python3

But both of these will fail if their corresponding Python version is not installed, since as far as I'm aware, systems that have Python 3 but not Python 2 do not alias or symlink python to python3. (Do correct me if I'm wrong.)

So is there a way to write a Python script with a shebang that will execute the script using either Python 2 or Python 3 so long as one of them is installed?

This is mainly intended to solve the removal of Python 2 from upcoming releases of macOS, (Note: I originally wrote that under the mistaken understanding that Python 2 would be replaced with Python 3 in macOS, but in reality Apple is removing Python completely.) but can apply to Linux as well.

like image 580
Bri Bri Avatar asked Mar 02 '23 10:03

Bri Bri


2 Answers

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")
like image 152
that other guy Avatar answered Mar 30 '23 00:03

that other guy


This seems to allow choosing python 3 over python 2, and will use either if found. Snagged from here, and allows you to deal with the situation where some people only have python 2 installed on their machine, and some only have python 3

#!/bin/bash
_='''' # Prefer python3 if it exists
command -v python3 &> /dev/null && exec python3 $0 "$@" || exec python $0 "$@"
'''
# Python code here
print ("Hello")
like image 30
Brad Parks Avatar answered Mar 29 '23 22:03

Brad Parks