En primer lugar, rara vez debe utilizar $*
y casi siempre debe usar "[email protected]"
en su lugar. Hay una serie de preguntas aquí en SO que explican los pormenores de por qué.
Segundo: el comando env
tiene dos usos principales. Una es imprimir el entorno actual; el otro es controlar completamente el entorno de un comando cuando se ejecuta. El tercer uso, que está demostrando, es modificar el entorno, pero francamente no hay necesidad de eso; los proyectiles son bastante capaces de manejar eso por usted.
Modo 1:
env
Modo 2:
env -i HOME=$HOME PATH=$PREPENDPATH:$PATH ... command args
Esta versión cancela todas las variables de entorno heredados y se ejecuta command
con precisión el entorno establecido por las opciones ENVVAR = valor.
El tercer modo, que modifica el entorno, es menos importante porque puedes hacerlo bien con las conchas normales (civilizadas). (. Esto significa "no shell C" - de nuevo, hay otras preguntas sobre SO con las respuestas que explican que) Por ejemplo, usted podría hacer perfectamente bien:
#!/bin/bash
export PATH=${PREPENDPATH:?}:$PATH
exec python "[email protected]"
Este insiste en que $PREPENDPATH
se establece en un país que no cadena vacía en el entorno, y luego lo antepone al $PATH
, y exporta la nueva configuración RUTA. Luego, utilizando esa nueva RUTA, ejecuta el programa python
con los argumentos relevantes. El exec
reemplaza el script de shell con python
. Tenga en cuenta que esto es bastante diferente de:
#!/bin/bash
PATH=${PREPENDPATH:?}:$PATH exec python "[email protected]"
Superficialmente, esto es lo mismo. Sin embargo, esto ejecutará el python
encontrado en el PATH preexistente, aunque con el nuevo valor de PATH en el entorno del proceso. Entonces, en el ejemplo, terminará ejecutando Python desde /usr/bin
y no desde el /home/pi/prepend/bin
.
En su situación, probablemente no usaría env
y solo usaría una variante apropiada de la secuencia de comandos con la exportación explícita.
El comando env
es inusual porque no reconoce el doble guión para separar las opciones del resto del comando. Esto se debe en parte a que no requiere muchas opciones, y en parte porque no está claro si las opciones ENVVAR = value deben aparecer antes o después del doble guión.
De hecho, tengo una serie de scripts para ejecutar (diferentes versiones de) un servidor de base de datos. Estos scripts realmente utilizan env
(y un montón de programas de cosecha propia) para controlar el entorno del servidor:
#!/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
Esta información es útil, pero como dice el PO, su/su núcleo no se ejecutará no binarios (como los sufragios bash que proporcionas) como primer elemento de una línea shebang. El mío tampoco lo hará; específicamente, el núcleo silenciosamente falla al ejecutar el script con la línea de shebang problemática en el intérprete deseado (no binario), y luego mi caparazón intentará ejecutar el script en su lugar. (Entiendo que este es un comportamiento de shell antiguo que conservan muchos shells.) – dubiousjim
¿No entiendo lo que dices? ¿Estás afirmando que hay (todavía) conchas o núcleos que no manejarán '#!/Bin/bash' o' #!/Bin/ksh' como la primera línea de un script? No estoy afirmando ni mostrando que puedes usar '#!/Some/script' como shebang. –
No reclamando el primero. Sin embargo, la pregunta del OP es sobre el segundo: preguntó: "¿Qué hace el kernel si insertas un guión de shell en la línea shebang?" y luego informa problemas que provienen de usar env.1 como una línea shebang, donde env.1 es un script. (Da la casualidad de que estaba buscando discusiones sobre las limitaciones de las líneas shebang que me trajeron aquí. Y encontré que tu publicación contenía información útil, así que gracias por contribuir. Estaba señalando, para otros lectores que vendrán después, que lo que discuten no ayuda a superar la limitación con la que OP se había enfrentado). – dubiousjim