User Tools

Site Tools


binfmt support for Python scripts

binfmt-misc is a way to “exec” non-native files using an interpreter. For example you can “exec” Windows .exe files using Wine or Linux binaries for another architecture using Qemu (by the way this is not widely known, but very useful – try mounting your Raspberry Pi into /mnt/foo and then “cp /usr/bin/qemu-arm-static /mnt/foo/usr/bin/; chroot /mnt/foo” - tadaa, you are now running your RPi system on your x86 desktop!)

Anyway, I'm lazy to type “#!/usr/bin/env python3” on the beginning of each single-use Python script, and lazy to execute it using “py3” instead of just “./”. I usually end up launching the “import” command from ImageMagick (sputtering weird screenshots across the filesystem) and then a bunch of shell errors.

So I just map all .py files to the python3 interpreter.

echo ":python3:E::py::/usr/bin/python3:" | sudo tee /proc/sys/fs/binfmt_misc/register

Btw. what's the difference between “#!/usr/bin/env python3” and “#!/usr/bin/python3”? There is one, besides the obvious one that weird systems may have Python installed in /opt and hardcoded path will thus not work: the kernel does not split argv for a hashbang command, so you can't pass multiple options! Try creating and running this:

/tmp> cat ./
#!/bin/bash -x -v
/tmp> ./
/bin/bash: - : invalid option

Fortunately, env will split it for you, at least when using -S:

> cat ./
#!/usr/bin/env -S bash -x -v
> ./ 
#!/usr/bin/env -S bash -x -v
+ true

Note that this feature has been ported from BSD into GNU Coreutils only recently (2018), so it will not work on older systems.

python-binfmt.txt · Last modified: 2019-01-16 03:30:35 (external edit)