Posso exportar uma variável para o ambiente a partir de um script bash sem fornecê-la?

282

Suponha que eu tenha esse script

export.bash :

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

Quando executo o script e tento acessar $VAR, não recebo valor!

echo $VAR

Existe alguma maneira de acessar o arquivo$VAR executando apenas export.bash sem fornecê- lo?

tarrsalah
fonte
1
Você pode tentar usar um alias em vez de um script para definir sua variável.
Jdigital 17/05
O script no qual estou trabalhando é algum tipo de gerenciador virtual java, eu faço alguns cálculos, então devo exportar um $ JAVA_HOME para o ambiente e anexá-lo ao PATH.
tarrsalah
Bem, você pode gravar as informações em um arquivo e depois lê-las novamente, mas o fornecimento parece muito mais fácil.
Jdigital 17/05
7
processos filhos não podem alterar o ambiente de seus pais. O pai tem que optar por alterar-se (quer com sourceou evalou ...)
Glenn Jackman
1
Para ler mais sobre fonte, man sourcenão vai funcionar porque sourceé construído em bash, você precisa executarhelp source
peterchaula

Respostas:

318

Existe alguma maneira de acessar o $VARarquivo apenas executando export.bashsem fornecê-lo?

Resposta rápida: Não.

Mas existem várias soluções possíveis.

O mais óbvio, que você já mencionou, é usar sourceou .executar o script no contexto do shell de chamada:

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

Outra maneira é ter o script, em vez de definir uma variável de ambiente, imprimir comandos que definirão a variável de ambiente:

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

Uma terceira abordagem é ter um script que defina suas variáveis ​​de ambiente internamente e depois invoque um comando especificado com esse ambiente:

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

Essa última abordagem pode ser bastante útil, embora seja inconveniente para uso interativo, pois não fornece as configurações no seu shell atual (com todas as outras configurações e histórico que você criou).

Keith Thompson
fonte
57

Para exportar a variável VAR primeiro, a maneira mais lógica e parece funcional é obter a variável:

. ./export.bash

ou

source ./export.bash

Agora, ao ecoar do shell principal, ele funciona

 echo $VAR
HELLO, VARABLE

Vamos agora redefinir o VAR

export VAR=""
echo $VAR

Agora vamos executar um script para originar a variável e depois desmarcá-la:

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

o 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

Aqui está uma maneira

ATENÇÃO: As exportações são limitadas ao script que executa as exportações no console principal - tanto quanto um trabalho cron, eu o adicionaria como o console como abaixo ... para a parte do comando ainda questionável: eis como você faria correr a partir do seu shell:

No prompt de comando (desde que o export.bash tenha vários 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

Agora, desde que seja para seu uso - você pode disponibilizar as variáveis ​​para seus scripts a qualquer momento, usando um alias do bash como este:

myvars ./v1.sh
HELLO THERE
HI THERE

echo $VAR

.

adicione isso ao seu .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

}

fonte seu arquivo bashrc e você pode fazer como acima a qualquer momento ...

De qualquer forma, de volta ao resto ..

Isso o tornou disponível globalmente e depois executou o script.

simplesmente faça eco e execute a exportação no eco!

cat export.bash

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

Agora no script ou no console, execute:

 export "$(./export.bash)"

Experimentar:

echo $VAR
HELLO THERE

Vários valores, desde que você saiba o que está esperando em outro script usando o método acima:

cat 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

Agora os resultados

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


.

e a atualização final final para atribuir automaticamente, leia as VARIÁVEIS:

./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

O 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
fonte
Quero exportar o VAR executando o arquivo, não fornecendo-o.
tarrsalah
@vahid, você deve explicar o que seu script está fazendo.
FDinoff 17/05
1
por que não desmarcar a variável após a fonte? ele ser muito mais fácil do que a dor a sua tentativa de fazer com que se irá atualizar o script de teste para a exportação
VH
Eu dei uma maneira alternativa de fazê-lo Tarrsalah
VH
atualizações finais ok - problemas com o método e trabalho arounds sugeriu a idéia bashrc apelido provavelmente seria uma ótima maneira para trás
VH
22

Executar

set -o allexport

Quaisquer variáveis ​​que você origine de um arquivo após isso serão exportadas para o seu shell.

source conf-file

Quando terminar, execute. Isso desativará o modo allexport.

set +o allexport
mdornfe1
fonte
7
O ponto principal da questão é "Como exportar sem fonte". Esta resposta usa fonte.
Vou I
@ekkis Sim, isso não responde exatamente à pergunta, mas sempre que eu pesquisava como exportar variáveis ​​de um arquivo, esse tópico aparecia. Então eu meio que coloquei lá para mim.
Mdornfe1
Simples e fácil de usar. isso deve ser marcado como a resposta.
QkiZ 27/09/19
1
Eu votei positivo porque a declaração original do problema me levou a entender que esta era minha solução fundamental. Há documentos oficiais sobre allexport aqui: gnu.org/software/bash/manual/html_node/The-Set-Builtin.html
benjaoming
ahh, +1. Esta pergunta é o principal resultado da palavra-chave bash source exportno Google
ttimasdf
14

Foi encontrada uma maneira interessante e interessante de exportar variáveis ​​de ambiente de um arquivo:

em env.vars:

foo=test

script de teste:

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
furgão
fonte
7

Outra solução alternativa que, dependendo do caso, pode ser útil: criar outra bash que herda a variável exportada. É um caso particular da resposta de @Keith Thompson, todos esses inconvenientes.

export.bash:

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

Agora:

./export.bash
echo $VAR
Gonmator
fonte
Tem certeza de que o que você escreveu funciona !? Eu acredito que você tem que executar o comando linha:. ./export.bash
Sir Jo Preto
@ Sir Jo Black, sim, com certeza. A última linha do arquivo export.bash é chamada bashcomo filho do shell atual. E como já VARfoi exportado antes, essa chamada incluirá a variável Obviamente, se você digitar, exito VARbotão sairá. Você já conferiu?
Gonmator
Está bem! Eu não vi essa invocação ...: p
Sir Jo Black
1

A resposta é não, mas para mim eu fiz o seguinte

o script: myExport

#! \bin\bash
export $1

um alias no meu .bashrc

alias myExport='source myExport' 

Mesmo assim, você a fonte, mas talvez seja mais utilizável e interessante para outra pessoa.

Malcomar
fonte
1

Talvez você possa escrever uma função em ~ / .zshrc, ~ / .bashrc.

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

Por causa da variável de uso externa, é possível evitar a gravação do arquivo de script.

zhi.yang
fonte