3

I used to add shebang line at top of Python script as,

#!/usr/bin/python ... 

And I can execute the my.py file by,

chmod a+r my.py ./my.py 

But after compiled to bytecode, the script can only be executed by python and the shebang does not work anymore.

python my.pyc 

Is there anyway to make shebang workable to compiled python script?

./my.pyc 
4
  • 2
    You're not supposed to execute .pyc files, why are you trying to do this? Commented Feb 17, 2014 at 10:03
  • 1
    We have to deliver the compiled pyc but not source code for our product. Commented Feb 19, 2014 at 1:05
  • Please bear in mind that full source code (including docstrings) can be recovered easily from Python bytecode with FOSS tools. There are some DIY techniques to make decompilation a bit more difficult, but there is no real obfuscator for Python. This is not to say that you should distribute full source code, of course, but remember that reversing pyc is almost trivial. Commented Feb 20, 2014 at 10:42
  • 2
    Hi Stefano, Thanks for your reminding. With delivering .pyc it usually means "ok I know you can decompile it but be aware that I do not like you do so." Commented Feb 24, 2014 at 0:40

3 Answers 3

7

Shebang works only for text scripts, not binary files. Nevertheless, you can use binfmt_misc to execute *.pyc files directly, as reported in this Python ML thread:

Linux, you can use binfmt_misc to make executables out of pyc code. Run:

import imp,sys,string magic = string.join(["\\x%.2x" % ord(c) for c in imp.get_magic()],"") reg = ':pyc:M::%s::%s:' % (magic, sys.executable) open("/proc/sys/fs/binfmt_misc/register","wb").write(reg) 

once on your Linux system (or, rather, at boot time), and all pyc files become executable (if the x bit is set).

In Debian, installing the binfmt-support package will do that for you.

(emphasis is mine, note that this will apply to all Debian derivatives, including Ubuntu. The same solution works in Fedora too).

Sign up to request clarification or add additional context in comments.

1 Comment

hi Stefano. this method supports many python versions (and .pyc) on the same host, right? can I set in procfs the python interpreter and one of its options?
0

No. But you can use other OS-specific mechanisms for invoking arbitrary executable files, e.g. binfmt_misc.

Comments

0

Here is an updated python 3 version of Stefano Sanfilippo's answer:

import imp,sys,string magic = "".join(["\\x%.2x" % c for c in imp.get_magic()]) reg = ':pyc:M::%s::%s:' % (magic, sys.executable) open("/proc/sys/fs/binfmt_misc/register","w").write(reg) 

1 Comment

importlib.util.MAGIC_NUMBER is the new replacement for imp according to docs.python.org/3/library/imp.html#imp.get_magic

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.