2009-07-21 16 views

Respuesta

714

export hace que la variable esté disponible para los subprocesos.

Es decir,

export name=value 

significa que el nombre de la variable está disponible para cualquier proceso se ejecuta a partir de ese proceso de shell. Si desea que un proceso haga uso de esta variable, use export y ejecute el proceso desde ese shell.

name=value 

significa que el ámbito de la variable está restringido al shell, y no está disponible para ningún otro proceso. Usted usaría esto para (por ejemplo) variables de bucle, variables temporales, etc.

Es importante tener en cuenta que exportar una variable no la hace disponible para procesos originales. Es decir, especificar y exportar una variable en un proceso generado no la hace disponible en el proceso que la lanzó.

+57

Específicamente exportación hace que la variable disponible para procesos secundarios través del medio ambiente. – Beano

+9

También agregaría que si la exportación está en un archivo que "fuente" (como .archivo) también lo exporta a su entorno de trabajo. – rogerdpack

+3

@rogerdpack ¿no puedes hacer eso sin exportar? cat> blah \ n a = hi \ n. paja; echo $ a; salidas 'hola' para mí. –

7

export hará que la variable a disposición de todos los depósitos en horquilla de la shell actual.

175

para ilustrar lo que las otras respuestas están diciendo:

al$ foo="Hello, World" 
al$ echo $foo 
Hello, World 
al$ bar="Goodbye" 
al$ export foo 
al$ bash 
bash-3.2$ echo $foo 
Hello, World 
bash-3.2$ echo $bar 

bash-3.2$ 
+6

Un ejemplo más para esto 'al $ foobar =" Whatever "bash' – Alun

60

Otros han respondido que la exportación hace que la variable a disposición de subniveles, y eso es correcto, sino simplemente un efecto secundario. Cuando exporta una variable, pone esa variable en el entorno del shell actual (es decir, el shell llama a 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.

+5

Tenga en cuenta que esto no es del todo cierto. En 'bash', export 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 simple de implementar la semántica de 'export', pero ese comportamiento no es obligatorio. –

+6

No estoy seguro de qué 'dash' tiene que ver con esto. El cartel original preguntaba específicamente sobre 'bash'. – Starfish

+11

La pregunta está etiquetada 'bash' pero se aplica igualmente a cualquier variante de bourne-shell. Ser demasiado específico y proporcionar respuestas que se aplican solo a 'bash' es un gran mal. –

3

Aquí hay otro ejemplo:

VARTEST="value of VARTEST" 
#export VARTEST="value of VARTEST" 
sudo env | grep -i vartest 
sudo echo ${SUDO_USER} ${SUDO_UID}:${SUDO_GID} "${VARTEST}" 
sudo bash -c 'echo ${SUDO_USER} ${SUDO_UID}:${SUDO_GID} "${VARTEST}"' 

Sólo mediante el uso de la exportación VARTEST el valor de VARTEST está disponible en sudo fiesta -c '...'!

Para más ejemplos, véase:

26

export NAME=value para los ajustes y variables que tener 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 copia en un subproceso y sus subprocesos al crearlo.Nunca se copia ningún nombre o valor del subproceso.

  • Un error común es colocar un espacio alrededor del signo igual:

    $ export FOO = "bar" 
    bash: export: `=': not a valid identifier 
    
  • Sólo la variable exportado (B) es visto por el subproceso:

    $ A="Alice"; export B="Bob"; echo "echo A is \$A. B is \$B" | bash 
    A is . B is Bob 
    
  • Cambios en el subproceso, no cambie el shell principal:

    $ export B="Bob"; echo 'B="Banana"' | bash; echo $B 
    Bob 
    
  • Variables marcadas para la exportación han 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 
    Subprocess 1 has B=Bob 
    Subprocess 2 has B=Banana 
    [1]+ Done   echo '(sleep 30; echo "Subprocess 1 has B=$B")' | bash 
    
  • Sólo exporta las variables se convierten en parte del entorno (man environ):

    $ ALICE="Alice"; export BOB="Bob"; env | grep "ALICE\|BOB" 
    BOB=Bob 
    

Por lo tanto, ¡ahora debería estar tan claro como el sol del verano! Gracias a Brain Agnew, alexp y William Prusell.

+0

+1 para mostrar errores comunes –

1

Aunque no se menciona explícitamente en el debate, NO es necesario usar exportar al generar una subshell desde dentro de bash ya que todas las variables se copian en el proceso hijo.

+0

Explique que lo que está diciendo parece contradecir directamente las respuestas con los ejemplos anteriores. –

+0

¡Esta es la manera correcta si no desea que las variables se exporten globalmente, sino que solo estén disponibles para el subproceso! Gracias. – jtblin

2

sólo para mostrar la diferencia entre una variable que está siendo exportado en el medio ambiente (ENV) y una variable no exportada no estar en el medio ambiente:

Si hago esto:

$ MYNAME=Fred 
$ export OURNAME=Jim 

entonces sólo $ OURNAME aparece en el env. La variable $ MYNAME no está en el env.

$ env | grep NAME 
OURNAME=Jim 

pero la variable de $ MINOMBRE existe en la cáscara

$ echo $MYNAME 
Fred 
35

Se ha dicho que no es necesario exportar en bash cuando el desove subniveles, mientras que otros dijeron exactamente lo contrario. Es importante tener en cuenta la diferencia entre subcapas (las creadas por (), ``, $() o bucles) y subprocesos (procesos que se invocan por nombre, por ejemplo, un literal bash que aparece en el script). Las subcapas tendrán acceso a todas las variables del elemento primario, independientemente de su estado exportado. Los subprocesos por otro lado serán solo ver las variables exportadas. Lo que es común en estos dos constructos es que ninguno de los dos puede pasar variables al shell primario.

$ noexport=noexport; export export=export; (echo subshell: $noexport $export; subshell=subshell); bash -c 'echo subprocess: $noexport $export; subprocess=subprocess'; echo parent: $subshell $subprocess 
subshell: noexport export 
subprocess: export 
parent: 

Hay otra fuente de confusión: algunos piensan que los subprocesos '' bifurcadas son los que no ven las variables no se exportan. Usualmente fork() s son seguidos inmediatamente por exec() s, y es por eso que parece que el fork() es lo que hay que buscar, mientras que de hecho es el exec().Puede ejecutar comandos sin tenedor (ing) en primer lugar con el comando exec y procesos iniciados por este método también no tendrá acceso a las variables no exportadas:

$ noexport=noexport; export export=export; exec bash -c 'echo execd process: $noexport $export; execd=execd'; echo parent: $execd 
execd process: export 

Tenga en cuenta que no vemos la parent: línea de este tiempo, porque hemos reemplazado el shell primario con el comando exec, por lo que no queda nada para ejecutar ese comando.

+2

Excelente resumen –

+0

Muy buena respuesta para mencionar la diferencia entre subcapas y subprocesos. Otra cosa: aunque las subcapas pueden leer todas las variables de la matriz, no puede alterar el valor de las variables en el elemento primario. – PickBoy

+0

Nunca he visto un bucle que (por sí mismo) creó una subshell; OTOH una tubería sí (siempre para piezas distintas a la última, a veces para la última depende de su caparazón, versión y opciones). Backgrounding ('&') también crea una subshell. –

0

De forma predeterminada, las variables creadas dentro de un script solo están disponibles para el shell actual; los procesos hijo (subconjuntos) no tendrán acceso a los valores que se han establecido o modificado. Permitir que los procesos secundarios vean los valores requiere el uso del comando de exportación.

5

Como ya sabrá, 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.

Programa

puede acceder a las variables del 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 las variables de entorno de procesos padre. 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 establecer sus variables de entorno a petición del usuario. Esto es para lo que existe export.

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 este Bash crearía.

Más sobre Environment in Bash

Otro tipo de variable en Bash es variable interna. Como Bash no es solo un intérprete interactivo, de hecho es un intérprete de guiones, 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 las 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 en Shell Parameters (incluyendo variables)

También vale la pena señalar que, de acuerdo con Bash manual de referencia:

El entorno para cualquier simple comando o función puede ser aumentada temporalmente prefijándolo con el parámetro asignaciones, como se describe en Shell Parameters. Estas instrucciones de asignación afectan solo al entorno visto por ese comando.


Para acabar:

  • export se utiliza para establecer la variable de entorno de sistema operativo. Esta variable estará disponible para todos los procesos secundarios creados por el proceso Bash actual para siempre.
  • La notación de la variable Bash (nombre = valor) se utiliza para establecer variables locales disponibles solo para el proceso actual de bash
  • La notación de la variable Bash prefijando otro comando crea una variable de entorno solo para el alcance de ese comando.
+0

bash vars no admiten tantos tipos como Python, pero sí tienen cadena, 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 cadena es _portable_. –

8

Cabe señalar que puede exportar una variable y luego cambiar el valor. El valor cambiado de la variable estará disponible para procesos secundarios. Una vez que se ha establecido la exportación para una variable, debe hacer export -n <var> para eliminar la propiedad.

$ K=1 
$ export K 
$ K=2 
$ bash -c 'echo ${K-unset}' 
2 
$ export -n K 
$ bash -c 'echo ${K-unset}' 
unset 
+0

Gracias, esta es exactamente la información que estaba buscando porque vi un script que usaba variables de entorno y luego las "reexportaba" con un nuevo valor, y me preguntaba si era necesario. –

+2

Este ejemplo es incorrecto. Aquí, '" echo $ K "' se expande a 'echo 2' _anyway_ antes de que el niño Bash se ejecute. Si quiere probar su punto, use comillas simples, para que el niño Bash vea '$ K' y lo expanda por sí mismo. – eepp

+0

@eepp Acabo de editar la respuesta para solucionar ese problema. –

2

Dos de los creadores de UNIX, Brian Kernighan y Rob Pike, explican esto en su libro "El entorno de programación UNIX". Busque el título de Google y encontrará fácilmente una versión en pdf.

se dirigen a las variables de shell en el apartado 3.6, y se centran en el uso del comando export al final de esa sección:

Cuando se quiere hacer que el valor de un acceso variable en sub-conchas, el comando de exportación del shell debe ser utilizado. (Puede pensar por qué no hay forma de exportar el valor de una variable desde un subconjunto a su elemento principal).

3

El accepted answer implica esto, pero me gustaría hacer explícita la conexión a desembolsar órdenes internas:

Como ya se ha mencionado, export hará una variable disponible tanto para la cáscara y los niños. Si export es no usado, la variable solo estará disponible en el shell, y solo los shell builtins pueden acceder a él.

Es decir,

tango=3 
env | grep tango # prints nothing, since env is a child process 
set | grep tango # prints tango=3 - "type set" shows `set` is a shell builtin 
Cuestiones relacionadas