Tangencialmente tenga en cuenta también que export name=valueno es portátil. Dependiendo de lo que quieras exactamente, prueba name=value; export namecon una solución portátil.
tripleee
Respuestas:
1055
export hace que la variable esté disponible para subprocesos.
Es decir,
export name=value
significa que el nombre de la variable está disponible para cualquier proceso que ejecute desde ese proceso de shell. Si desea que un proceso haga uso de esta variable, use exporty ejecute el proceso desde ese shell.
name=value
significa que el alcance variable está restringido al shell y no está disponible para ningún otro proceso. Usaría esto para (digamos) variables de bucle, variables temporales, etc.
Es importante tener en cuenta que exportar una variable no la pone a disposición de los procesos principales. Es decir, especificar y exportar una variable en un proceso generado no la hace disponible en el proceso que la lanzó.
Específicamente, la exportación hace que la variable esté disponible para los procesos secundarios a través del entorno.
Beano el
15
También agregaría que si la exportación está en un archivo que usted "origina" (como. Nombre de archivo), también lo exporta a su entorno de trabajo.
rogerdpack
66
@rogerdpack ¿no puedes hacer eso sin exportar? gato> bla \ na = hola \ n. paja; echo $ a; salidas 'hola' para mí.
David Winiecki
2
Agradable funciona incluso sin la exportación. Así que supongo que al comprar un archivo, si se utiliza la exportación que se reflejará en los procesos secundarios, si no se acaba de afectar al medio ambiente local de fiesta ...
rogerdpack
19
Hay un caso extremo para esto; name=value commandhace que la variable esté disponible en el subproceso command.
Otros han respondido que exportar hace que la variable esté disponible para subcapas, y eso es correcto pero simplemente un efecto secundario. Cuando exporta una variable, la coloca en el entorno del shell actual (es decir, el shell llama putenv(3)o setenv(3)).
El entorno de un proceso se hereda a través de exec, lo que hace que la variable sea visible en subcapas.
Editar (con perspectiva de 5 años): esta es una respuesta tonta. El propósito de 'exportar' es hacer que las variables "se encuentren en el entorno de los comandos ejecutados posteriormente", ya sean comandos o subprocesos. Una implementación ingenua sería simplemente poner la variable en el entorno del shell, pero esto haría que sea imposible de implementar export -p.
Tenga en cuenta que esto no es del todo cierto. En bash, export de hecho agrega la variable al entorno del shell actual, pero este no es el caso con dash. Me parece que agregar la variable al entorno del shell actual es la forma más sencilla de implementar la semántica de export, pero ese comportamiento no es obligatorio.
William Pursell
77
No estoy seguro de qué dashtiene que ver esto. El póster original preguntaba específicamente sobre bash.
Starfish
14
La pregunta está etiquetada bashpero se aplica igualmente a cualquier variante de caparazón de bourne. Ser demasiado específico y proporcionar respuestas que se aplican solo a bashes un gran mal.
William Pursell
12
bashes el jQuery del shell.
Potherca
2
export makes the variable available to subshells, and that is correctEste es un uso muy confuso de la terminología. Las subcapas no necesitan exportheredar variables. Los subprocesos sí.
Amit Naidu
62
Se ha dicho que no es necesario exportar en bash cuando se generan subcapas, mientras que otros dicen exactamente lo contrario. Es importante tener en cuenta la diferencia entre subniveles (aquellos que son creados por (), ``, $()o bucles) y subprocesos (procesos que se invocan por su nombre, por ejemplo, un literal bashque aparece en el script).
Los shells secundarios tendrán acceso a todas las variables del padre, independientemente de su estado exportado.
Sub procesos serán solamente ver las variables exportadas.
Lo que es común en estas dos construcciones es que ninguna de las dos puede devolver variables al shell principal.
Hay otra fuente de confusión: algunos piensan que los subprocesos 'bifurcados' son los que no ven variables no exportadas. Por lo general, los fork () s son seguidos inmediatamente por exec () s, y es por eso que parece que el fork () es lo que debe buscarse, mientras que de hecho es el exec (). Puede ejecutar comandos sin fork () primero con el execcomando, y los procesos iniciados por este método tampoco tendrán acceso a variables no exportadas:
Tenga en cuenta que parent:esta vez no vemos la línea, porque hemos reemplazado el shell principal con el execcomando, por lo que no queda nada para ejecutar ese comando.
Nunca he visto un bucle que (por sí mismo) haya creado una subshell; OTOH lo hace una tubería (siempre para piezas diferentes a la última, a veces para la última dependiendo de su shell, versión y opciones). Backgrounding ( &) también crea una subshell.
dave_thompson_085
¿Qué hay de estos var=asdf bash -c 'echo $var'o var=asdf exec bash -c 'echo $var'? La salida es asdf. La ;diferencia se coloca después de la definición de la variable. ¿Cuál sería la explicación? Parece que el var(sin ;) respecto al subproceso generado de alguna manera, debido a que el shell de origen no tiene nada que ver con eso. echo $varno imprime nada si se ejecuta en la segunda línea. Pero uno alineado var=asdf bash -c 'echo $var'; echo $varda asdf\nasdf.
4xy
31
export NAME=value para configuraciones y variables que tienen significado para un subproceso.
NAME=value para variables temporales o de bucle privadas para el proceso de shell actual.
Con más detalle, exportmarca el nombre de la variable en el entorno que se copia en un subproceso y sus subprocesos en el momento de la creación. Ningún nombre o valor se copia del subproceso.
Un error común es colocar un espacio alrededor del signo igual:
$ export FOO ="bar"
bash: export:`=': not a valid identifier
El Bsubproceso solo ve la variable exportada ( ):
$ A="Alice"; export B="Bob"; echo "echo A is \$A. B is \$B"| bash
A is . B is Bob
Los cambios en el subproceso no cambian el shell principal:
$ export B="Bob"; echo 'B="Banana"'| bash; echo $B
Bob
Las variables marcadas para exportación tienen valores copiados cuando se crea el subproceso:
$ export B="Bob"; echo '(sleep 30; echo "Subprocess 1 has B=$B")'| bash &[1]3306
$ B="Banana"; echo '(sleep 30; echo "Subprocess 2 has B=$B")'| bash
Subprocess1 has B=BobSubprocess2 has B=Banana[1]+Done echo '(sleep 30; echo "Subprocess 1 has B=$B")'| bash
Solo las variables exportadas se vuelven parte del entorno ( man environ):
Cabe señalar que puede exportar una variable y luego cambiar el valor. El valor modificado de la variable estará disponible para los procesos secundarios. Una vez que se ha establecido la exportación para una variable, debe hacer export -n <var>para eliminar la propiedad.
Gracias, esta es exactamente la información que estaba buscando porque vi un script que usaba variables de entorno y luego las "reexporté" con un nuevo valor, y me preguntaba si era necesario.
Mike Lippert
8
Como ya sabrás, UNIX permite que los procesos tengan un conjunto de variables de entorno, que son pares clave / valor, tanto la clave como el valor son cadenas. El sistema operativo es responsable de mantener estos pares para cada proceso por separado.
El programa puede acceder a sus variables de entorno a través de esta API UNIX:
char *getenv(const char *name);
int setenv(const char *name, const char *value, int override);
int unsetenv(const char *name);
Los procesos también heredan variables de entorno de los procesos primarios. El sistema operativo es responsable de crear una copia de todos los "envars" en el momento en que se crea el proceso secundario.
Bash , entre otros shells, es capaz de configurar sus variables de entorno a petición del usuario. Para eso exportexiste.
exportes un comando Bash para establecer la variable de entorno para Bash. Todas las variables establecidas con este comando serían heredadas por todos los procesos que crearía este Bash.
Otro tipo de variable en Bash es la variable interna. Dado que Bash no es solo un shell interactivo, de hecho es un intérprete de script, como cualquier otro intérprete (por ejemplo, Python) es capaz de mantener su propio conjunto de variables. Cabe mencionar que Bash (a diferencia de Python) solo admite variables de cadena.
La notación para definir variables de Bash es name=value. Estas variables permanecen dentro de Bash y no tienen nada que ver con las variables de entorno que mantiene el sistema operativo.
También vale la pena señalar que, de acuerdo con el manual de referencia de Bash:
El entorno para cualquier comando o función simple puede aumentarse temporalmente con el prefijo con asignaciones de parámetros, como se describe en Parámetros de Shell . Estas declaraciones de asignación afectan solo al entorno visto por ese comando.
Para resumir las cosas:
exportse usa para establecer la variable de entorno en el sistema operativo. Esta variable estará disponible para todos los procesos secundarios creados por el proceso Bash actual para siempre.
La notación de variables bash (nombre = valor) se usa para establecer variables locales disponibles solo para el proceso actual de bash
La notación de la variable Bash que antepone otro comando crea una variable de entorno solo para el alcance de ese comando.
bash vars no admite tantos tipos como Python, pero tiene una cadena, un entero y dos tipos de matriz ('indexada' / tradicional y 'asociativa' que es similar a awk array, perl hash o Python dict). Otras conchas varían; Solo la cuerda es portátil .
dave_thompson_085
7
La respuesta aceptada implica esto, pero me gustaría hacer explícita la conexión a los componentes integrados de shell:
Como ya se mencionó, exporthará que una variable esté disponible tanto para el shell como para los hijos. Si exportse no se utiliza, la variable sólo estará disponible en la cáscara, y sólo la cáscara órdenes internas se puede acceder a él.
Es decir,
tango=3
env | grep tango # prints nothing, since env is a child processset| grep tango # prints tango=3 - "type set" shows `set` is a shell builtin
Dos de los creadores de UNIX, Brian Kernighan y Rob Pike, explican esto en su libro "El entorno de programación de UNIX". Busque el título en Google y encontrará fácilmente una versión en pdf.
Abordan las variables de shell en la sección 3.6 y se centran en el uso del exportcomando al final de esa sección:
Cuando desee que el valor de una variable sea accesible en subcapas, se debe usar el comando de exportación del caparazón. (Puede pensar en por qué no hay forma de exportar el valor de una variable desde un sub-shell a su padre).
Solo para mostrar la diferencia entre una variable exportada que se encuentra en el entorno (env) y una variable no exportada que no se encuentra en el entorno:
Si hago esto:
$ MYNAME=Fred
$ export OURNAME=Jim
entonces solo $ OURNAME aparece en la env. La variable $ MYNAME no está en el entorno.
Por defecto, las variables creadas dentro de un script solo están disponibles para el shell actual; Los procesos secundarios (subcapas) no tendrán acceso a los valores que se hayan establecido o modificado. Permitir que los procesos secundarios vean los valores requiere el uso del comando de exportación.
Aunque no se menciona explícitamente en la discusión, NO es necesario usar exportar cuando se genera una subshell desde adentro de bash ya que todas las variables se copian en el proceso secundario.
export name=value
no es portátil. Dependiendo de lo que quieras exactamente, pruebaname=value; export name
con una solución portátil.Respuestas:
export
hace que la variable esté disponible para subprocesos.Es decir,
significa que el nombre de la variable está disponible para cualquier proceso que ejecute desde ese proceso de shell. Si desea que un proceso haga uso de esta variable, use
export
y ejecute el proceso desde ese shell.significa que el alcance variable está restringido al shell y no está disponible para ningún otro proceso. Usaría esto para (digamos) variables de bucle, variables temporales, etc.
Es importante tener en cuenta que exportar una variable no la pone a disposición de los procesos principales. Es decir, especificar y exportar una variable en un proceso generado no la hace disponible en el proceso que la lanzó.
fuente
name=value command
hace que la variable esté disponible en el subprocesocommand
.Para ilustrar lo que dicen las otras respuestas:
fuente
al$ foobar="Whatever" bash
Otros han respondido que exportar hace que la variable esté disponible para subcapas, y eso es correcto pero simplemente un efecto secundario. Cuando exporta una variable, la coloca en el entorno del shell actual (es decir, el shell llama
putenv(3)
osetenv(3)
).El entorno de un proceso se hereda a través de exec, lo que hace que la variable sea visible en subcapas.
Editar (con perspectiva de 5 años): esta es una respuesta tonta. El propósito de 'exportar' es hacer que las variables "se encuentren en el entorno de los comandos ejecutados posteriormente", ya sean comandos o subprocesos. Una implementación ingenua sería simplemente poner la variable en el entorno del shell, pero esto haría que sea imposible de implementar
export -p
.fuente
bash
, export de hecho agrega la variable al entorno del shell actual, pero este no es el caso condash
. Me parece que agregar la variable al entorno del shell actual es la forma más sencilla de implementar la semántica deexport
, pero ese comportamiento no es obligatorio.dash
tiene que ver esto. El póster original preguntaba específicamente sobrebash
.bash
pero se aplica igualmente a cualquier variante de caparazón de bourne. Ser demasiado específico y proporcionar respuestas que se aplican solo abash
es un gran mal.bash
es el jQuery del shell.export makes the variable available to subshells, and that is correct
Este es un uso muy confuso de la terminología. Las subcapas no necesitanexport
heredar variables. Los subprocesos sí.Se ha dicho que no es necesario exportar en bash cuando se generan subcapas, mientras que otros dicen exactamente lo contrario. Es importante tener en cuenta la diferencia entre subniveles (aquellos que son creados por
()
,``
,$()
o bucles) y subprocesos (procesos que se invocan por su nombre, por ejemplo, un literalbash
que aparece en el script).Lo que es común en estas dos construcciones es que ninguna de las dos puede devolver variables al shell principal.
Hay otra fuente de confusión: algunos piensan que los subprocesos 'bifurcados' son los que no ven variables no exportadas. Por lo general, los fork () s son seguidos inmediatamente por exec () s, y es por eso que parece que el fork () es lo que debe buscarse, mientras que de hecho es el exec (). Puede ejecutar comandos sin fork () primero con el
exec
comando, y los procesos iniciados por este método tampoco tendrán acceso a variables no exportadas:Tenga en cuenta que
parent:
esta vez no vemos la línea, porque hemos reemplazado el shell principal con elexec
comando, por lo que no queda nada para ejecutar ese comando.fuente
&
) también crea una subshell.var=asdf bash -c 'echo $var'
ovar=asdf exec bash -c 'echo $var'
? La salida esasdf
. La;
diferencia se coloca después de la definición de la variable. ¿Cuál sería la explicación? Parece que elvar
(sin;
) respecto al subproceso generado de alguna manera, debido a que el shell de origen no tiene nada que ver con eso.echo $var
no imprime nada si se ejecuta en la segunda línea. Pero uno alineadovar=asdf bash -c 'echo $var'; echo $var
daasdf\nasdf
.export NAME=value
para configuraciones y variables que tienen significado para un subproceso.NAME=value
para variables temporales o de bucle privadas para el proceso de shell actual.Con más detalle,
export
marca el nombre de la variable en el entorno que se copia en un subproceso y sus subprocesos en el momento de la creación. Ningún nombre o valor se copia del subproceso.Un error común es colocar un espacio alrededor del signo igual:
El
B
subproceso solo ve la variable exportada ( ):Los cambios en el subproceso no cambian el shell principal:
Las variables marcadas para exportación tienen valores copiados cuando se crea el subproceso:
Solo las variables exportadas se vuelven parte del entorno (
man environ
):Entonces, ¡ahora debería estar tan claro como el sol del verano! Gracias a Brain Agnew, alexp y William Prusell.
fuente
export
hará que la variable esté disponible para todos los shells bifurcados del shell actual.fuente
Cabe señalar que puede exportar una variable y luego cambiar el valor. El valor modificado de la variable estará disponible para los procesos secundarios. Una vez que se ha establecido la exportación para una variable, debe hacer
export -n <var>
para eliminar la propiedad.fuente
Como ya sabrás, UNIX permite que los procesos tengan un conjunto de variables de entorno, que son pares clave / valor, tanto la clave como el valor son cadenas. El sistema operativo es responsable de mantener estos pares para cada proceso por separado.
El programa puede acceder a sus variables de entorno a través de esta API UNIX:
char *getenv(const char *name);
int setenv(const char *name, const char *value, int override);
int unsetenv(const char *name);
Los procesos también heredan variables de entorno de los procesos primarios. El sistema operativo es responsable de crear una copia de todos los "envars" en el momento en que se crea el proceso secundario.
Bash , entre otros shells, es capaz de configurar sus variables de entorno a petición del usuario. Para eso
export
existe.export
es un comando Bash para establecer la variable de entorno para Bash. Todas las variables establecidas con este comando serían heredadas por todos los procesos que crearía este Bash.Más sobre el medio ambiente en Bash
Otro tipo de variable en Bash es la variable interna. Dado que Bash no es solo un shell interactivo, de hecho es un intérprete de script, como cualquier otro intérprete (por ejemplo, Python) es capaz de mantener su propio conjunto de variables. Cabe mencionar que Bash (a diferencia de Python) solo admite variables de cadena.
La notación para definir variables de Bash es
name=value
. Estas variables permanecen dentro de Bash y no tienen nada que ver con las variables de entorno que mantiene el sistema operativo.Más sobre los parámetros de Shell (incluidas las variables)
También vale la pena señalar que, de acuerdo con el manual de referencia de Bash:
Para resumir las cosas:
export
se usa para establecer la variable de entorno en el sistema operativo. Esta variable estará disponible para todos los procesos secundarios creados por el proceso Bash actual para siempre.fuente
La respuesta aceptada implica esto, pero me gustaría hacer explícita la conexión a los componentes integrados de shell:
Como ya se mencionó,
export
hará que una variable esté disponible tanto para el shell como para los hijos. Siexport
se no se utiliza, la variable sólo estará disponible en la cáscara, y sólo la cáscara órdenes internas se puede acceder a él.Es decir,
fuente
Aquí hay otro ejemplo más:
¡Solo usando export VARTEST el valor de VARTEST está disponible en sudo bash -c '...'!
Para más ejemplos ver:
http://mywiki.wooledge.org/SubShell
bash-hackers.org/wiki/doku.php/scripting/processtree
fuente
Dos de los creadores de UNIX, Brian Kernighan y Rob Pike, explican esto en su libro "El entorno de programación de UNIX". Busque el título en Google y encontrará fácilmente una versión en pdf.
Abordan las variables de shell en la sección 3.6 y se centran en el uso del
export
comando al final de esa sección:fuente
Solo para mostrar la diferencia entre una variable exportada que se encuentra en el entorno (env) y una variable no exportada que no se encuentra en el entorno:
Si hago esto:
entonces solo $ OURNAME aparece en la env. La variable $ MYNAME no está en el entorno.
pero la variable $ MYNAME existe en el shell
fuente
Por defecto, las variables creadas dentro de un script solo están disponibles para el shell actual; Los procesos secundarios (subcapas) no tendrán acceso a los valores que se hayan establecido o modificado. Permitir que los procesos secundarios vean los valores requiere el uso del comando de exportación.
fuente
Aunque no se menciona explícitamente en la discusión, NO es necesario usar exportar cuando se genera una subshell desde adentro de bash ya que todas las variables se copian en el proceso secundario.
fuente