Прежде всего, вы должны очень редко использовать $*
, и вы должны почти всегда использовать "[email protected]"
. На SO есть ряд вопросов, которые объясняют причины и причины.
Вторая команда env
имеет два основных вида использования. Один - напечатать текущую среду; другой - полностью контролировать среду команды при ее запуске. Третье использование, которое вы демонстрируете, - это изменить среду, но, откровенно говоря, в этом нет необходимости - оболочки вполне способны справиться с этим для вас.
Режим 1:
env
Режим 2:
env -i HOME=$HOME PATH=$PREPENDPATH:$PATH ... command args
Эта версия отменяет все унаследованные переменные окружения и запускает command
именно с окружающей средой, установленной опции ENVVAR = значение.
Третий режим - изменение окружающей среды - менее важен, поскольку вы можете делать это нормально с помощью обычных (цивилизованных) оболочек. (. Это означает, что «не C оболочки» - опять же, есть и другие вопросы по SO с ответами, которые объясняют, что) Например, вы могли бы прекрасно сделать:
#!/bin/bash
export PATH=${PREPENDPATH:?}:$PATH
exec python "[email protected]"
Это настаивает на том, что $PREPENDPATH
настроен на не- пустую строку в среде, а затем добавляет ее в $PATH
и экспортирует новую настройку PATH. Затем, используя этот новый PATH, он выполняет программу python
с соответствующими аргументами. exec
заменяет скрипт оболочки python
. Обратите внимание, что это совсем не так:
#!/bin/bash
PATH=${PREPENDPATH:?}:$PATH exec python "[email protected]"
Поверхностно, это то же самое. Однако это приведет к выполнению python
, найденному на ранее существовавшем PATH, но с новым значением PATH в среде процесса. Итак, в этом примере вы закончите выполнение Python с /usr/bin
, а не с /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 "[email protected]"
case "$*" in
(*v*) track-oninit-v $stdout;;
esac
Это полезная информация, но, как говорит О. П., его/ее ядро не будет работать не- бинарные файлы (например, бас-заглушки, которые вы предоставляете) в качестве первого элемента линии shebang. Мой тоже не будет; в частности, ядро не запускает скрипт с проблематичной линией shebang в желаемом (не двоичном) интерпретаторе, а затем моя оболочка будет пытаться запустить скрипт. (Мое недопонимание заключается в том, что это старое поведение оболочки, которое сохраняет множество оболочек.) – dubiousjim 2012-04-23 17:41:35