まず第一に、使用することはめったになく$*
、ほとんどの場合、代わりに使用する必要があります"$@"
。SOには、その理由の詳細を説明する多くの質問があります。
2番目-env
コマンドには2つの主な用途があります。1つは、現在の環境を印刷することです。もう1つは、コマンドの実行時にコマンドの環境を完全に制御することです。あなたが示している3番目の使用法は、環境を変更することですが、率直に言って、その必要はありません-シェルはあなたのためにそれを処理することができます。
モード1:
env
モード2:
env -i HOME=$HOME PATH=$PREPENDPATH:$PATH ... command args
このバージョンは、継承されたすべての環境変数をキャンセルcommand
し、ENVVAR=valueオプションで設定された環境で正確に実行されます。
3番目のモード(環境の修正)は、通常の(文明化された)シェルでうまく実行できるため、それほど重要ではありません。(これは「Cシェルではない」という意味です。これも、SOに関する他の質問と、それを説明する回答があります。)たとえば、次のように完全に実行できます。
#!/bin/bash
export PATH=${PREPENDPATH:?}:$PATH
exec python "$@"
これは$PREPENDPATH
、環境内で空でない文字列に設定されていることを要求し、それをの前に$PATH
追加して、新しいPATH設定をエクスポートします。次に、その新しいPATHを使用してpython
、関連する引数を使用してプログラムを実行します。はexec
、シェルスクリプトを。に置き換えますpython
。これは次のものとはまったく異なることに注意してください。
#!/bin/bash
PATH=${PREPENDPATH:?}:$PATH exec python "$@"
表面的には、これは同じです。ただし、これpython
により、プロセスの環境でPATHの新しい値が使用されていても、既存のPATHで検出されたものが実行されます。/usr/bin
したがって、この例では、からではなく、からPythonを実行することになります/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