Diferença entre variáveis ​​de shell que são exportadas e aquelas que não estão no bash

41

O Bash parece diferenciar entre variáveis ​​que foram exportadas e aquelas que não foram.

exemplo:

$ FOO=BAR
$ env | grep FOO
$ set | grep FOO
FOO=BAR

setvê a variável, mas envnão.

$ export BAR=FOO
$ env | grep FOO
BAR=FOO
$ set | grep FOO
BAR=FOO
FOO=BAR

setvê as duas variáveis, mas envvê apenas a variável exportada.

Eu sei que seté um bash embutido e envnão é.

Quais são as diferenças entre as variáveis ​​exportadas e as que não são?

lesmana
fonte
17
Nota de terminologia: uma "variável de ambiente" é sempre exportada. Uma variável não exportada é uma "variável de shell" (ou "parâmetro").
Gilles 'SO- stop be evil'

Respostas:

44

As variáveis ​​exportadas são transportadas para o ambiente de comandos executados pelo shell que os exportou, enquanto as variáveis ​​não exportadas são locais para a chamada de shell atual. Na exportpágina do manual:

O shell deve atribuir o atributo export às variáveis ​​correspondentes aos nomes especificados, o que fará com que elas estejam no ambiente de comandos executados posteriormente.

setgera o ambiente atual, que inclui quaisquer variáveis ​​locais não exportadas. envé usado para iniciar programas em um novo ambiente e, sem argumentos, produzirá o que seria esse novo ambiente. Como envestá criando um novo ambiente, somente variáveis ​​exportadas são trazidas, como é o caso de qualquer programa iniciado a partir desse shell. Por exemplo, gerando um segundo shell dentro do primeiro (eu costumava $$representar prompts no shell interno):

$ FOO=BAR
$ bash
$$ echo $FOO             # Note the empty line

$$ exit
$ export FOO
$ bash
$$ echo $FOO
BAR
$$

Observe que é a variável exportada, não apenas seu valor. Isto significa que uma vez que você export FOO, FOOtorna-se uma variável global e mostra-se em ambientes posteriores, mesmo se mudou mais tarde:

$ export FOO
$ FOO=BAR
$ bash
$$ echo $FOO
BAR
$$
Michael Mrozek
fonte
portanto, se você está preocupado apenas com o shell atual, precisa exportar? Separadamente, por que localeo shell atual não mostraria as atualizações?
Pacerier