First of all, you should very rarely use $* , and you should almost always use " $@ " . There are a number of questions on SO that explain the reasons and the reasons why.
Second, the env command has two main uses. One is to print the current environment; the other is to fully control the team environment when it starts. The third use that you demonstrate is a change in environment, but frankly, there is no need for it - shells are quite capable of handling this for you.
Mode 1:
env
Mode 2:
env -i HOME=$HOME PATH=$PREPENDPATH:$PATH ... command args
This version cancels all inherited environment variables and runs command with the exact environment specified by the ENVVAR = value parameters.
The third mode - changing the environment - is less important, because you can do it normally using ordinary (civilized) shells. (This means that the “non-C shell” - again, there are other SO questions with answers that explain this.) For example, you may well be able to do this:
#!/bin/bash export PATH=${PREPENDPATH:?}:$PATH exec python " $@ "
This means that $PREPENDPATH set to a non-empty string in the environment, and then adds it to $PATH and exports the new PATH setting. Then, using this new PATH, it executes the python program with the corresponding arguments. exec replaces the shell script with python . Please note that this is very different from:
#!/bin/bash PATH=${PREPENDPATH:?}:$PATH exec python " $@ "
Superficially, this is the same. However, this will be done by python found on a pre-existing PATH, albeit with a new PATH value in the production environment. So, in this example, you end Python execution from /usr/bin , and not from /home/pi/prepend/bin .
In your situation, I would probably not use env and just use the appropriate script option with explicit export.
The env command is unusual because it does not recognize a double dash to separate parameters from the rest of the command. This is partly due to the fact that many options are not required, and partly due to the fact that it is unclear whether the parameter values ENVVAR = before or after the double dash.
In fact, I have a series of scripts to run (different versions) of a database server. These scripts really use env (and a bunch of home programs) to manage the server environment:
#!/bin/ksh # # @(#)$Id: boot.black_19.sh,v 1.3 2008/06/25 15:44:44 jleffler Exp $ # # Boot server black_19 - IDS 11.50.FC1 IXD=/usr/informix/11.50.FC1 IXS=black_19 cd $IXD || exit 1 IXF=$IXD/do.not.start.$IXS if [ -f $IXF ] then echo "$0: will not start server $IXS because file $IXF exists" 1>&2 exit 1 fi ONINIT=$IXD/bin/oninit.$IXS if [ ! -f $ONINIT ] then ONINIT=$IXD/bin/oninit fi tmpdir=$IXD/tmp DAEMONIZE=/work1/jleffler/bin/daemonize stdout=$tmpdir/$IXS.stdout stderr=$tmpdir/$IXS.stderr if [ ! -d $tmpdir ] then asroot -u informix -g informix -C -- mkdir -p $tmpdir fi # Specialized programs carried to extremes: # * asroot sets UID and GID values and then executes # * env, which sets the environment precisely and then executes # * daemonize, which makes the process into a daemon and then executes # * oninit, which is what we really wanted to run in the first place! # NB: daemonize defaults stdin to /dev/null and could set umask but # oninit dinks with it all the time so there is no real point. # NB: daemonize should not be necessary, but oninit doesn't close its # controlling terminal and therefore causes cron-jobs that restart # it to hang, and interactive shells that started it to hang, and # tracing programs. # ??? Anyone want to integrate truss into this sequence? asroot -u informix -g informix -C -a dbaao -a dbsso -- \ env -i HOME=$IXD \ INFORMIXDIR=$IXD \ INFORMIXSERVER=$IXS \ INFORMIXCONCSMCFG=$IXD/etc/concsm.$IXS \ IFX_LISTEN_TIMEOUT=3 \ ONCONFIG=onconfig.$IXS \ PATH=/usr/bin:$IXD/bin \ SHELL=/usr/bin/ksh \ TZ=UTC0 \ $DAEMONIZE -act -d $IXD -o $stdout -e $stderr -- \ $ONINIT " $@ " case "$*" in (*v*) track-oninit-v $stdout;; esac