¿Puedo exportar una variable al entorno desde un script bash sin obtenerla?

282

Supongamos que tengo este script

export.bash :

#! /usr/bin/env bash
export VAR="HELLO, VARIABLE"

Cuando ejecuto el script e intento acceder al $VAR, no obtengo ningún valor.

echo $VAR

¿Hay alguna forma de acceder al archivo$VAR simplemente ejecutando export.bash sin obtenerlo ?

tarrsalah
fuente
1
Puede intentar usar un alias en lugar de un script para definir su variable.
jdigital
El script en el que estoy trabajando es una especie de administrador virtual de Java, hago algunos cálculos y luego debo exportar un $ JAVA_HOME al entorno y agregarlo a PATH.
tarrsalah
Bueno, podría escribir la información en un archivo y luego volver a leerla, pero el abastecimiento parece mucho más fácil.
jdigital
77
los procesos secundarios no pueden alterar el entorno de sus padres. El padre tiene que elegir modificarse (ya sea con sourceo evalo ...)
Glenn Jackman
1
Para leer más sobre la fuente, man sourceno funcionará porque sourceestá integrado en bash, debes ejecutarlohelp source
peterchaula

Respuestas:

319

¿Hay alguna forma de acceder al $VARsimplemente ejecutando export.bashsin obtenerlo?

Respuesta rápida: no.

Pero hay varias soluciones posibles.

El más obvio, que ya ha mencionado, es usar sourceo .ejecutar el script en el contexto del shell de llamada:

$ cat set-vars1.sh 
export FOO=BAR
$ . set-vars1.sh 
$ echo $FOO
BAR

Otra forma es tener el script, en lugar de establecer una variable de entorno, comandos de impresión que establecerán la variable de entorno:

$ cat set-vars2.sh
#!/bin/bash
echo export FOO=BAR
$ eval "$(./set-vars2.sh)"
$ echo "$FOO"
BAR

Un tercer enfoque es tener un script que establezca las variables de entorno internamente y luego invoque un comando específico con ese entorno:

$ cat set-vars3.sh
#!/bin/bash
export FOO=BAR
exec "$@"
$ ./set-vars3.sh printenv | grep FOO
FOO=BAR

Este último enfoque puede ser bastante útil, aunque es inconveniente para el uso interactivo, ya que no le brinda la configuración en su shell actual (con todas las demás configuraciones e historial que ha creado).

Keith Thompson
fuente
57

Para exportar primero la variable VAR, la forma más lógica y que parece funcionar es obtener la variable:

. ./export.bash

o

source ./export.bash

Ahora cuando hace eco desde el shell principal funciona

 echo $VAR
HELLO, VARABLE

Ahora reiniciaremos VAR

export VAR=""
echo $VAR

Ahora ejecutaremos un script para obtener la variable y luego la desarmaremos:

./test-export.sh 
HELLO, VARABLE
--
.

el código: cat test-export.sh

    #!/bin/bash
    # Source env variable
    source ./export.bash

    # echo out the variable in test script
    echo $VAR

    # unset the variable 
    unset VAR
    # echo a few dotted lines
    echo "---"
    # now return VAR which is blank
    echo $VAR

Aquí hay una manera

TENGA EN CUENTA: Las exportaciones se limitan al script que ejecuta las exportaciones en su consola principal, por lo que en lo que respecta a un trabajo cron, lo agregaría como la consola como a continuación ... para la parte del comando aún cuestionable: así es como lo haría corre desde tu caparazón:

En el símbolo del sistema (siempre que export.bash tenga varios valores de eco)

IFS=$'\n'; for entries in $(./export.bash); do  export $entries;  done; ./v1.sh 
HELLO THERE
HI THERE

cat v1.sh

#!/bin/bash
echo $VAR
echo $VAR1

Ahora, siempre que sea para su uso, puede hacer que las variables estén disponibles para sus scripts en cualquier momento haciendo un alias bash como este:

myvars ./v1.sh
HELLO THERE
HI THERE

echo $VAR

.

agregue esto a su .bashrc

function myvars() { 
    IFS=$'\n'; 
    for entries in $(./export.bash); do  export $entries;  done; 

    "$@"; 

    for entries in $(./export.bash); do variable=$(echo $entries|awk -F"=" '{print $1}'); unset $variable;
done

}

fuente de su archivo bashrc y puede hacer lo anterior en cualquier momento ...

De todos modos volviendo al resto ...

Esto lo ha hecho disponible globalmente y luego ejecutó el script.

¡simplemente repítelo y luego ejecuta export en el eco!

gato export.bash

#!/bin/bash
echo "VAR=HELLO THERE"

Ahora dentro del script o su consola ejecute:

 export "$(./export.bash)"

Tratar:

echo $VAR
HELLO THERE

Múltiples valores siempre que sepa lo que espera en otro script utilizando el método anterior:

gato export.bash

#!/bin/bash
echo "VAR=HELLO THERE"
echo "VAR1=HI THERE"

cat test-export.sh

#!/bin/bash

IFS=$'\n'
for entries in $(./export.bash); do
   export $entries
done

echo "round 1"
echo $VAR
echo $VAR1

for entries in $(./export.bash); do
     variable=$(echo $entries|awk -F"=" '{print $1}');
     unset $variable
done

echo "round 2"
echo $VAR
echo $VAR1

Ahora los resultados

 ./test-export.sh 
round 1
HELLO THERE
HI THERE
round 2


.

y la actualización final final para la asignación automática lee las VARIABLES:

./test-export.sh 
Round 0 - Export out then find variable name - 
Set current variable to the variable exported then echo its value
$VAR has value of HELLO THERE
$VAR1 has value of HI THERE
round 1 - we know what was exported and we will echo out known variables
HELLO THERE
HI THERE
Round 2 - We will just return the variable names and unset them 
round 3 - Now we get nothing back

El script: cat test-export.sh

#!/bin/bash

IFS=$'\n'
echo "Round 0 - Export out then find variable name - "
echo "Set current variable to the variable exported then echo its value"
for entries in $(./export.bash); do
 variable=$(echo $entries|awk -F"=" '{print $1}');
 export $entries
 eval current_variable=\$$variable
 echo "\$$variable has value of $current_variable"
done


echo "round 1 - we know what was exported and we will echo out known variables"
echo $VAR
echo $VAR1

echo "Round 2 - We will just return the variable names and unset them "
for entries in $(./export.bash); do
 variable=$(echo $entries|awk -F"=" '{print $1}');
 unset $variable
done

echo "round 3 - Now we get nothing back"
echo $VAR
echo $VAR1
VH
fuente
Quiero exportar VAR ejecutando el archivo, no obteniéndolo.
tarrsalah
@vahid deberías explicar qué está haciendo tu script.
FDinoff
1
¿Por qué no desarmar la variable después del abastecimiento? será mucho más fácil que el dolor que estás tratando de causarte actualizará el script de prueba-exportación
VH
Le di una forma alternativa de hacerlo Tarrsalah
VH
ok actualizaciones finales: los problemas con el método sugerido y la solución de la idea de alias bashrc probablemente serían una excelente manera de hacerlo
VH
22

Ejecutar

set -o allexport

Cualquier variable que obtenga de un archivo después de esto se exportará a su shell.

source conf-file

Cuando termines, ejecuta. Esto deshabilitará el modo allexport.

set +o allexport
mdornfe1
fuente
77
El punto completo de la pregunta es "Cómo exportar sin fuente". Esta respuesta usa la fuente.
Gonen I
@ekkis Sí, no responde exactamente la pregunta, pero cada vez que busqué en Google cómo exportar variables de un archivo surgió este hilo. Así que solo lo puse allí para mí.
mdornfe1
Simple y fácil de usar. Esto debe ser marcado como la respuesta.
QkiZ
1
Voté esto porque la declaración original del problema me llevó a comprender que esta era mi solución fundamental. Hay documentos oficiales en allexport aquí: gnu.org/software/bash/manual/html_node/The-Set-Builtin.html
benjaoming
ahh, +1. Esta pregunta es el resultado principal de la palabra clave bash source exporten Google
ttimasdf
14

Encontró una forma interesante y ordenada de exportar variables de entorno desde un archivo:

en env.vars:

foo=test

script de prueba:

eval `cat env.vars`
echo $foo         # => test
sh -c 'echo $foo' # => 

export eval `cat env.vars`
echo $foo         # => test
sh -c 'echo $foo' # => test

# a better one
export `cat env.vars`
echo $foo         # => test
sh -c 'echo $foo' # => test
camioneta
fuente
7

Otra solución alternativa que, según el caso, podría ser útil: crear otro bash que herede la variable exportada. Es un caso particular de respuesta @Keith Thompson, tendrá todos esos inconvenientes.

export.bash:

# !/bin/bash
export VAR="HELLO, VARIABLE"
bash

Ahora:

./export.bash
echo $VAR
Gonmator
fuente
¿Estás seguro de que lo que escribiste funciona? Creo que debe ejecutar el comando de línea:. ./export.bash
Sir Jo Black,
@ Sir Jo Black, sí, claro. La última línea del archivo export.bash se invoca bashcomo hijo del shell actual. Y como VARse exportó antes, esa invocación incluirá la variable. Por supuesto, si escribe exitla VARva a salir. ¿Te fijaste?
Gonmator
¡Okay! No he visto esa invocación ...: p
Sir Jo Black
1

La respuesta es no, pero para mí hice lo siguiente

el script: myExport

#! \bin\bash
export $1

un alias en mi .bashrc

alias myExport='source myExport' 

Aún así lo obtienes, pero tal vez de esta manera es más útil y es interesante para otra persona.

Malcomar
fuente
1

Tal vez pueda escribir una función en ~ / .zshrc, ~ / .bashrc.

# set my env
[ -s ~/.env ] && export MYENV=`cat ~/.env`
function myenv() { [[ -s ~/.env ]] && echo $argv > ~/.env && export MYENV=$argv }

Debido al uso de variables externas, puede evitar escribir un archivo de script.

zhi.yang
fuente