Generic Shell(!) Wrapper For *.py Modules

Tim Cargile tecargile at hotmail.com
Thu Jan 9 18:11:54 CET 2003


Reusable/linkable shell wrapper for 'execing' Python *.py modules
located in any directory on PYTHONPATH. Supports multi-word args.

Beats keeping *.py modules in 'bin' directories ... or does it?
Yep.  It's shell(!), but let's not forget scripting language roots
and its biggest success story (after PERL, of course ... errr I
mean Python).

:-)


#--------------------------- cut here ------------------------------
#!/bin/ksh
#-------------------------------------------------------------------
cat_man_page() {  #--- This Function Can Be Deleted AS Necessary
                  #--- $PN = sh2py
#-------------------------------------------------------------------
cat <<-EOF | more
  ------------------------------------------------------------------
  $PN(1)                                                   $PN(1)


  NAME
        $PN - Exec Python script from a shell script (shell wrapper)

  SYNOPSIS

        $PN [ python_script_args ]

  DESCRIPTION

        $PN executes '*.py' files of same name as a shell script.
        This will provide Python run of files named '*.py' while
        maintaining the 'no-suffix' convention for UNIX executables
        and the avoidance of identifying the source language in
        executable file names.  

        $PN also provides for the storage of Python modules in 
        directories other than 'bin' directories.  These directories
        must be in the PYTHONPATH environment variable to enable 
        $PN to locate the Python module(s).

        $PN will search PYTHONPATH directories for the file to
        run having the same run 'basename' as the script but with
        the '.py' suffix.  If found, the $PN script will replace
        its process by 'execing' either the Python interpreter
        or the Python file directly.

        Arguments are passed to the Python interpreter or to the
        scripts with the preservation of single and multi-word
        argument word grouping.

        Since $PN does not alter Python environment variables,
        the environment (especally PYTHONPATH) should be set
        correctly (and exported) for desired Python interpreter
        operation prior to execution or unexpected behavior may occur.


  OPTIONS

        None

  NOTES

        The $PN base script can be hard or soft linked to multiple
        desired file names to support multiple executable files.

  ENVIRONMENT VARIABLES

        PYTHONPATH - Searched for files to edit if not found in
                     the current directory.

  INSTALLATION

        Example of a Python script '${prefix}/python/foo.py'
        module where '${prefix}/python' is in PYTHONPATH:

        $ cp $PN ${prefix}/bin  #--- If $PN does not already exist 
        $ cd ${prefix}/bin
     *  $ ln $PN foo            #--- If 'foo' does not already exist

     *) Links would be used if it is desired to have a single, master
        copy of the $PN script.  However, it may be desirable to
        have the 'target' script a copy if changes are to be made
        that support one or more specific Python modules, for example.


  BUGS/DEFICIENCIES

        Uncompiled Python scripts without the '.py' suffix are
        not supported.  Of course, nobody would think to create an
        uncompiled Python script without the '.py' suffix in an
        attempt to hide the fact that it is written in Python.
        In any event, a shell wrapper may not be necessary for
        such modules if they are installed in 'bin' directories
        and follow the "#!" first-line convention to identify the
        Python interpreter.

  AUTHOR

        Tim Cargile (510) 914-4809 / 1/8/2002

  SEE ALSO

        python(1), bash(1), ksh(1)


  $PN(1)                                                   $PN(1)
  ------------------------------------------------------------------
EOF
}

#PN=`basename $0`;cat_man_page;exit  #--- Delete. For manual page only

#---
#--- Default PYTHONPATH to CWD if null
#--- THIS CAN/SHOULD BE CHANGED TO IDENTIFY OTHER/ANOTHER DEFAULT
#--- DIRECTORY.
#---
if [ -z "$PYTHONPATH" ]; then
    PYTHONPATH="./"
fi

#---
#--- Maintain argument multi-word boundaries
#---
unset args

while [ $# -gt 0 ];do
    args="$args \"$1\""
    shift
done

#---------------------------------------------------------------
#--- Look for Python module in each PYTHONPATH directory
#--- and run the first one found
#---------------------------------------------------------------
py_module_bn=`basename $0`
py_module=${py_module_bn}.py
py_exec=python
#---
#--- Set InterField Seperator to parse PYTHONPATH
#---
IFS_SAVE=$IFS
IFS=:

for dir in $PYTHONPATH;do 
    if [ -r ${dir}/$py_module ];then
        IFS=$IFS_SAVE

        #--- 
        #--- Run mode determined by first line of Python Script
        #--- Change this if all scripts have 'first line' command
        #--- 

        fl=`head -1 ${dir}/${py_module}`

        case "$fl" in
        \#!*)   eval exec ${dir}/${py_module} "$args"  ;;
        *)      eval exec $py_exec ${dir}/${py_module} "$args"  ;;
        esac

        break  #--- This should NOT occur ... but could happen, Dude!
    fi
done

echo "$py_module_bn: Cannot find python module: $py_module" >&2
echo "$py_module_bn: PYTHONPATH = $PYTHONPATH" >&2

exit 2




More information about the Python-list mailing list