This is a handy way to package a group of python modules into a single compressed self-extracting python executable script. This works on UNIX and Cygwin with Python 2.3 Final or later.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
#!/bin/sh # This is a self-extracting executable. # Execute this like any normal executable. # You may need to "chmod a+x" this file. # This is a binary ZIP file with a Python loader header. # # Bourne shell loader: PYTHON=$(which python 2>/dev/null) if [ ! -x "$PYTHON" ] ; then echo "Python not found!" exit 1 fi exec $PYTHON -c " # Python loader: import sys, os if int(sys.version)<2: print 'Python version 2.3 final or greater is required.' print 'Your version is', sys.version os._exit(1) major = sys.version_info minor = sys.version_info releaselevel = sys.version_info if (major==2 and minor<3) or (major==2 and minor==3 and releaselevel!='final'): print 'Python version 2.3 final or greater is required.' print 'Your version is', sys.version os._exit(1) sys.path.insert(0, sys.argv) del sys.argv[0:1] import MY_SCRIPT MY_SCRIPT.main() " $0 $@ # Zip file:
Assume the following situation: * you have a script called MY_SCRIPT.py with a main() function. * your script imports a number of other modules in the local directory. * you want to distribute this script to others as a single executable script that does not require installation or unpacking of all the other modules.
Step 1. Compress your project into a ZIP file:
zip MY_SCRIPT.ZIP *.py
Step 2. Add the shell script header source to the ZIP file. Be sure to change the two references to MY_SCRIPT to the actual name of your script:
cat zip_header.sh MY_SCRIPT.ZIP > SCRIPT
Step 3. Make the SCRIPT executable.
chmod 775 SCRIPT
Step 4. Now run your self-extracting executable ./SCRIPT
This does not corrupt the ZIP file and it is a valid shell script even though it is binary. This is a wrapper, within a wrapper, within a wrapper, but it actually works and it isn't too complicated to build for most projects.
Python is able to run code inside of a ZIP file. The shell script header starts python which runs another pythin script header that loads and run the main function in your script.
make if __name__ == '__main__' work. Replace:
After this change a script with the __name__ == '__main__' trick works, no need to specify a main() function.
Anything added beyond. Anything added beyond the script does not get printed to the screen why?
Like is added echo 'Hello'
Which does get printed to the screen