Una especie de pregunta secundaria, pero ¿cómo se llama la característica en sí cuando configura una variable de entorno para un solo subcomando como ese? Siempre me ha costado encontrar información sobre esto porque no sé cómo se llama.
John Cromartie
1
@ JohnCromartie, deberías hacer eso como una pregunta.
@ JohnCromartie Es un componente opcional de cada comando de shell, por lo que se encuentra en la sección "Comandos simples" de la mayoría de los manuales de shell. Para POSIX, eso estaría aquí . Glenn ya te ha vinculado la sección análoga del manual de bash.
jw013
Establecer una variable que no existe a través de una asignación crea una variable de shell. Configurarlo a través de ENV o exportar la variable empuja la variable al entorno de ejecución del shell. Cambiar el valor de una variable existente actualizará el valor del entorno de ejecución si existe, de lo contrario, cámbielo en las variables internas del shell.
Johan
Respuestas:
26
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.
Sin FOO=bar exec bazembargo, puede hacerlo , por lo que no necesita enven su último punto.
Stéphane Chazelas
Cuando execalgo, ¿utiliza su entorno actual?
Glenn Jackman
1
Lo mismo ocurre con @StephaneChazelas, y también puede sudo FOO=bar bazpasar variables de entorno sin necesidad de hacerlo env.
Mike Miller
1
@StephaneChazelas que solo funciona si quiero incluir FOO=barel script. Si FOOno es siempre bar, no quiero a codificar ella, y en su lugar lo paso en.
Patrick
@glennjackman sí, siempre y cuando las variables se exporten o se pasen antes del exec, como FOO=bar exec baz.
Patrick
14
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
Cuando solía usar tcsh, escribía (setenv FOO bar; baz)para obtener la función equivalente.
Barmar
6
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:
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.
Respuestas:
Son funcionalmente equivalentes.
La principal diferencia es que
env FOO=bar baz
implica invocar un proceso intermedio entre el shell ybaz
, donde al igual que conFOO=bar baz
el shell, invoca directamentebaz
.Por lo tanto, en ese sentido,
FOO=bar baz
se prefiere.Las únicas situaciones en las que me encuentro usando
env FOO=bar
es 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
exec
el comando que se le pasó, como:Si lo ejecutas como
myscript FOO=bar baz
,exec
arrojará un error comoexec FOO=bar baz
no válido.En cambio, lo llama como
myscript env FOO=bar baz
que se ejecuta comoexec env FOO=bar baz
, y es perfectamente válido.fuente
FOO=bar exec baz
embargo, puede hacerlo , por lo que no necesitaenv
en su último punto.exec
algo, ¿utiliza su entorno actual?sudo FOO=bar baz
pasar variables de entorno sin necesidad de hacerloenv
.FOO=bar
el script. SiFOO
no es siemprebar
, no quiero a codificar ella, y en su lugar lo paso en.exec
, comoFOO=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
baz
es un ejecutable y no un shell incorporado.Si su shell no es compatible con POSIX, por ejemplo ,
csh
otcsh
la sintaxisno funciona y no hay una sintaxis de shell equivalente. Para esas conchas, el
env
comando es la única forma de anular o inyectar variables de entorno para un solo comando.Si
baz
es un shell integrado, digamos,fc
por ejemplo,env
no dará los mismos resultados, porqueenv
está ejecutando un nuevo proceso en lugar de ser ejecutado directamente por el shell del comando. Además, no hay unfc
ejecutable, solo puede ejecutarse como un shell integrado debido a la forma en que interactúa con el entorno del shell, y también loenv
hará nunca funcionará con un tipo incorporadofc
.Además,
env
ofrece la-i
opción, que le permite iniciar un comando en un entorno vacío con solo un conjunto específico de variables de entorno. Porenv
lo tanto, puede ser muy útil para iniciar procesos en entornos desinfectados, por ejemplofuente
tcsh
, escribía(setenv FOO bar; baz)
para obtener la función equivalente.Además de lo que ya se ha dicho
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:
O
bash
no te permite hacer:Si bien puedes hacer:
(no es que quieras o debas querer hacer eso). O:
(A veces necesito hacer eso).
Tenga en cuenta que con
env
usted todavía no puede pasar una cadena de variable de entorno que no contenga un=
(no es que tampoco quiera hacerlo).fuente
Un uso de
env
es permitir la$PATH
búsqueda de ejecutables en líneas shebang (porqueenv
considera$PATH
cuando busca el ejecutable). Esto es útil si el ejecutable que desea invocar puede estar en diferentes lugares en diferentes máquinas. Por ejemplo,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/perl
o 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.fuente
Otro momento en el que
env
es 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 usandoenv
al final de un script que establece un montón de variables con los valores correctos:La
-i
opción elimina el entorno existente. LasVAR=value
opciones 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 pasaINFORMIXSQLHOSTS="$IXH"
aenv
si$IXH
se establece en un valor no vacío.fuente