首先,您应该很少使用$*
并且几乎总是应该使用"$@"
。这里有很多关于 SO 的问题,可以解释原因的来龙去脉。
其次 - 该env
命令有两个主要用途。一是打印当前环境;另一种是完全控制命令运行时的环境。您正在演示的第三个用途是修改环境,但坦率地说,没有必要这样做——shell 完全有能力为您处理。
模式一:
env
模式二:
env -i HOME=$HOME PATH=$PREPENDPATH:$PATH ... command args
这个版本取消了所有继承的环境变量,并command
在 ENVVAR=value 选项设置的环境下运行。
第三种模式 - 修改环境 - 不太重要,因为您可以使用常规(文明)外壳很好地做到这一点。(这意味着“不是 C shell”——同样,还有其他关于 SO 的问题的答案可以解释这一点。)例如,你可以很好地做到:
#!/bin/bash
export PATH=${PREPENDPATH:?}:$PATH
exec python "$@"
这坚持$PREPENDPATH
设置为环境中的非空字符串,然后将其添加到$PATH
,并导出新的 PATH 设置。然后,使用新的 PATH,它python
使用相关参数执行程序。将exec
shell 脚本替换为python
. 请注意,这与以下内容完全不同:
#!/bin/bash
PATH=${PREPENDPATH:?}:$PATH exec python "$@"
从表面上看,这是一样的。但是,这将python
在预先存在的 PATH 上执行找到的,尽管在进程的环境中使用 PATH 的新值。因此,在示例中,您最终将执行 Python from/usr/bin
而不是 from /home/pi/prepend/bin
。
在您的情况下,我可能不会使用env
并且只会使用具有显式导出的适当脚本变体。
该env
命令不寻常,因为它无法识别用于将选项与命令的其余部分分开的双破折号。这部分是因为它不需要很多选项,部分是因为不清楚 ENVVAR=value 选项应该出现在双破折号之前还是之后。
我实际上有一系列用于运行(不同版本)数据库服务器的脚本。这些脚本真正使用env
(和一堆自制程序)来控制服务器的环境:
#!/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