Pregunta Definir una variable con o sin exportación


Que es export ¿para?

Cuál es la diferencia entre:

export name=value

y

name=value

685
2017-07-21 09:09


origen


Respuestas:


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 huyes de ese proceso de shell. Si desea que un proceso haga uso de esta variable, use export, y ejecuta el proceso desde ese caparazón.

name=value

significa que el alcance 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 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ó.


771
2017-07-21 09:45



Para ilustrar lo que dicen las otras respuestas:

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

bash-3.2$ 

193
2017-07-21 09:56



Otros han respondido que la exportación hace que la variable esté disponible para las subcapas, y eso es correcto, pero 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.

Editar (con 5 años de perspectiva): esta es una respuesta tonta. El propósito de 'exportar' es hacer que las variables "estén en el entorno de los comandos subsiguientemente ejecutados", ya sea que esos comandos sean subcapas o subprocesos. Una implementación ingenua sería simplemente poner la variable en el entorno del shell, pero esto haría imposible implementar export -p.


63
2017-07-21 10:33



Se ha dicho que no es necesario exportar en bash cuando se generan subcapas, mientras que otros dicen exactamente lo contrario. Es importante notar la diferencia entre las subcapas (aquellas que son creadas por (), ``, $() o bucles) y subprocesos (procesos que se invocan por nombre, por ejemplo, un literal bash apareciendo en tu script). Subshells será tener acceso a todas las variables del padre, independientemente de su estado exportado. Los subprocesos por otro lado solamente 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:

Existe una fuente más de confusión: algunos piensan que los subprocesos "bifurcados" son los que no ven las variables no exportadas. 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 fork () primero con el exec comando, y los procesos iniciados con este método tampoco tendrán 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 el parent: línea esta vez, porque hemos reemplazado el shell padre con el exec comando, por lo que no queda nada para ejecutar ese comando.


43
2018-02-12 08:16



export NAME=value para configuraciones y variables que tienen significado para un subproceso.

NAME=value para variables temporales o de bucle privadas al 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 momento de la creación. 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
    
  • Solo la variable exportada (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
    
  • 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 
    Subprocess 1 has B=Bob
    Subprocess 2 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)

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

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


26
2018-04-24 17:10



Debe tenerse en cuenta 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 de 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

9
2018-02-10 16:36



export hará que la variable esté disponible para todos los shells bifurcados desde el shell actual.


8
2017-07-21 09:10



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.

El programa puede acceder a sus variables de entorno a través de esta API de 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 principales. El sistema operativo es responsable de crear una copia de todos los "envars" en el momento en que se crea el proceso secundario.

Intento, entre otros shells, es capaz de establecer sus variables de entorno a petición del usuario. Esto es lo que export existe para.

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 en Medio ambiente en Bash

Otro tipo de variable en Bash es la 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 Parámetros de Shell (incluyendo variables)

También vale la pena señalar que, según el manual de referencia de Bash:

El entorno para cualquier comando o función simple puede ser aumentado   temporalmente añadiéndole prefijos con asignaciones de parámetros, como se describe   en Parámetros de Shell. Estas declaraciones de asignación afectan solo al   ambiente visto por ese comando.


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.
  • 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 variable Bash prefijando otro comando crea una variable de entorno solo para el alcance de ese comando.

5
2018-06-19 16:48



los respuesta aceptada implica esto, pero me gustaría hacer explícita la conexión a los builtins de shell:

Como ya se mencionó, export hará que una variable esté disponible tanto para el shell como para los hijos. Si export es no utilizado, la variable solo estará disponible en el shell, y solo el shell builtins puede acceder a ella.

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

5
2017-09-22 07:33