Difference between revisions of "Self-extracting Python Script"

From Noah.org
Jump to navigationJump to search
Line 3: Line 3:
 
== Build a compressed self-extracting executable script on UNIX ==
 
== Build a compressed self-extracting executable script on UNIX ==
  
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.
+
This shows how to build a compressed self-extracting script.
 +
This is a handy way to package a group of python modules into a single compressed self-extracting executable script.
 +
This works on UNIX and Cygwin with Python 2.3 Final or later.
  
 
<pre>
 
<pre>

Revision as of 05:52, 7 June 2007

Build a compressed self-extracting executable script on UNIX

This shows how to build a compressed self-extracting script. This is a handy way to package a group of python modules into a single compressed self-extracting executable script. This works on UNIX and Cygwin with Python 2.3 Final or later.

#!/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[0])<2:
    print 'Python version 2.3 final or greater is required.'
    print 'Your version is', sys.version
    os._exit(1)
major = sys.version_info[0]
minor = sys.version_info[1]
releaselevel = sys.version_info[3]
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[1])
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.