¿Cuál es la diferencia entre el comando
$ env FOO=bar baz
y
$ FOO=bar baz
¿Qué efecto envtiene?
¿Cuál es la diferencia entre el comando
$ env FOO=bar baz
y
$ FOO=bar baz
¿Qué efecto envtiene?
Respuestas:
Son funcionalmente equivalentes.
La principal diferencia es que env FOO=bar bazimplica invocar un proceso intermedio entre el shell y baz, donde al igual que con FOO=bar bazel shell, invoca directamente baz.
Por lo tanto, en ese sentido, FOO=bar bazse prefiere.
Las únicas situaciones en las que me encuentro usando env FOO=bares donde tengo que pasar un comando a otro comando.
Como ejemplo específico, digamos que tengo un script de contenedor que realiza algunas modificaciones del entorno y luego invoca execel comando que se le pasó, como:
#!/bin/bash
FOO=bob
some stuff
exec "$@"
Si lo ejecutas como myscript FOO=bar baz , execarrojará un error como exec FOO=bar bazno válido.
En cambio, lo llama como myscript env FOO=bar bazque se ejecuta como exec env FOO=bar baz, y es perfectamente válido.
FOO=bar exec bazembargo, puede hacerlo , por lo que no necesita enven su último punto.
execalgo, ¿utiliza su entorno actual?
sudo FOO=bar bazpasar variables de entorno sin necesidad de hacerlo env.
FOO=barel script. Si FOOno es siempre bar, no quiero a codificar ella, y en su lugar lo paso en.
exec, como FOO=bar exec baz.
En este ejemplo en particular, no existe una diferencia efectiva, suponiendo que su shell es un shell compatible con POSIX, y suponiendo que bazes un ejecutable y no un shell incorporado.
Si su shell no es compatible con POSIX, por ejemplo , csho tcshla sintaxis
FOO=bar baz
no funciona y no hay una sintaxis de shell equivalente. Para esas conchas, elenv comando es la única forma de anular o inyectar variables de entorno para un solo comando.
Si bazes un shell integrado, digamos, fcpor ejemplo, envno dará los mismos resultados, porque envestá ejecutando un nuevo proceso en lugar de ser ejecutado directamente por el shell del comando. Además, no hay un fcejecutable, solo puede ejecutarse como un shell integrado debido a la forma en que interactúa con el entorno del shell, y también lo envhará nunca funcionará con un tipo incorporado fc.
Además, envofrece la -iopción, que le permite iniciar un comando en un entorno vacío con solo un conjunto específico de variables de entorno. Por envlo tanto, puede ser muy útil para iniciar procesos en entornos desinfectados, por ejemplo
env -i HOME=/tmp/homedir "PATH=`getconf PATH`" "TERM=$TERM" FOO=bar baz
tcsh, escribía (setenv FOO bar; baz)para obtener la función equivalente.
Además de lo que ya se ha dicho
VAR=value cmd args > redirs
Al ser una función de shell (Bourne / POSIX), está limitado en el nombre de las variables de entorno a las que pasa cmd. Deben ser nombres de variables de shell válidos y no deben ser de solo lectura o variables especiales para el shell.
Por ejemplo, no puedes hacer:
1=foo cmd
O
+++=bar cmd
bash no te permite hacer:
SHELLOPTS=xtrace cmd
Si bien puedes hacer:
env 1=foo cmd
env +++=bar cmd
env '=baz' cmd
(no es que quieras o debas querer hacer eso). O:
env SHELLOPTS=xtrace cmd
(A veces necesito hacer eso).
Tenga en cuenta que con envusted todavía no puede pasar una cadena de variable de entorno que no contenga un =(no es que tampoco quiera hacerlo).
Un uso de enves permitir la $PATHbúsqueda de ejecutables en líneas shebang (porque envconsidera $PATHcuando busca el ejecutable). Esto es útil si el ejecutable que desea invocar puede estar en diferentes lugares en diferentes máquinas. Por ejemplo,
#!/usr/bin/env perl
en la primera línea de un script con conjunto de bits ejecutable ejecutará este script con Perl sin importar si está instalado en /usr/bin/perlo en/usr/local/bin/perl o en un lugar completamente diferente, siempre que el directorio esté en la ruta.
Por supuesto, esa búsqueda de ruta conlleva un riesgo adicional, pero el riesgo no es mayor que si hubiera escrito explícitamente perl yourscript.pl, lo que también busca perl en la ruta de búsqueda.
Otro momento en el que enves realmente útil es si desea controlar el entorno por completo. Ejecuto un programa de servidor (Informix, en caso de que no pueda adivinar) cuyo entorno quiero controlar por completo. Lo ejecuto usando enval final de un script que establece un montón de variables con los valores correctos:
env -i HOME="$IXD" \
INFORMIXDIR="$IXD" \
INFORMIXSERVER="$IXS" \
${IXC:+INFORMIXCONCSMCFG="$IXC"} \
${IXH:+INFORMIXSQLHOSTS="$IXH"} \
IFX_LISTEN_TIMEOUT=3 \
ONCONFIG="onconfig.$IXS" \
PATH="/bin:/usr/bin:$IXD/bin" \
SHELL=/bin/ksh \
TZ=UTC0 \
$ONINIT "$@"
La -iopción elimina el entorno existente. Las VAR=valueopciones posteriores establecen las variables de entorno que quiero establecer; el nombre del programa está en $ONINIT, y cualquier argumento de línea de comando se pasa literalmente con "$@".
La ${IXH:+INFORMIXSQLHOSTS="$IXH"}construcción solo pasa INFORMIXSQLHOSTS="$IXH"a envsi $IXHse establece en un valor no vacío.