Possible approach
In Linux you can use binfmt_misc
. See the documentation, it states:
First you must mount binfmt_misc
:
mount binfmt_misc -t binfmt_misc /proc/sys/fs/binfmt_misc
but Debian or Ubuntu (and possibly other distros that use systemd) mount this automatically out of the box. If mount | grep binfmt_misc
shows binfmt_misc
mounted on /proc/sys/fs/binfmt_misc
then it's already set up.
You can manually assign /usr/bin/python3
to the py
"extension" by invoking:
echo ':py:E::py::/usr/bin/python3:' | sudo tee /proc/sys/fs/binfmt_misc/register
For completeness, this is how you manually unregister:
echo -1 | sudo tee /proc/sys/fs/binfmt_misc/py
To make the assignment survive reboots (if your Linux uses systemd-binfmt.service
), create a py.conf
file in /etc/binfmt.d/
with the following content:
# Run .py files with /usr/bin/python3
:py:E::py::/usr/bin/python3:
See man 5 binfmt.d
for details.
My tests indicate the defined interpreter wins with the shebang, if any. In other words: after applying the above, a shebang in a *.py
file will be irrelevant, /usr/bin/python3
will be used anyway.
Personal view
The approach works and you may even like it, I'm not a fan of it though. My reasons:
If you sometimes forget the shebang, you can forget the py
"extension" as well. Frankly, in my opinion you should forget it, because…
"Extensions" for executable files are ugly. Imagine you have rewritten your tool.py
in C or whatever; are you going to change the filename? If so, everything that uses tool.py
must be updated. If the file was named tool
from the beginning, then the world could start using the new release just like that, maybe even without realizing something has changed. Relying on magic bytes (like the shebang) makes this easy.