Observe também tangencialmente que export name=valuenão é portátil. Dependendo do que exatamente você deseja, tente name=value; export nameuma solução portátil.
tripleee
Respostas:
1054
export torna a variável disponível para subprocessos.
Isso é,
export name=value
significa que o nome da variável está disponível para qualquer processo executado a partir desse processo de shell. Se você deseja que um processo faça uso dessa variável, use exporte execute o processo nesse shell.
name=value
significa que o escopo da variável é restrito ao shell e não está disponível para nenhum outro processo. Você usaria isso para (digamos) variáveis de loop, variáveis temporárias etc.
É importante observar que a exportação de uma variável não a torna disponível para processos-pai. Ou seja, especificar e exportar uma variável em um processo gerado não a torna disponível no processo que a iniciou.
Especificamente, a exportação disponibiliza a variável para os processos filhos por meio do ambiente.
Beano
15
Eu também acrescentaria que, se a exportação estiver em um arquivo que você "origina" (como. Filename), também a exporta para o seu ambiente de trabalho.
Rogerdpack 17/09/2013
6
@rogerdpack você não pode fazer isso sem exportar? gato> blá \ na = oi \ n. blá; eco $ a; gera 'oi' para mim.
David Winiecki
2
Bom, funciona mesmo sem a exportação. Então eu acho que quando adquirem um arquivo, se você usar exportação que será refletido em processos filhos, se você não só vai afetar o meio ambiente festa locais ...
rogerdpack
19
Há um caso extremo nisso; name=value commandnão fazer a variável disponível no sub-processo command.
Oliver Charlesworth
254
Para ilustrar o que as outras respostas estão dizendo:
Mais um exemplo para isto #al$ foobar="Whatever" bash
Alun 15/06
70
Outros responderam que a exportação disponibiliza a variável para subshells, e isso é correto, mas apenas um efeito colateral. Quando você exporta uma variável, ela a coloca no ambiente do shell atual (ou seja, o shell chama putenv(3)ou setenv(3)).
O ambiente de um processo é herdado entre exec, tornando a variável visível em subshells.
Editar (com perspectiva de 5 anos): esta é uma resposta boba. O objetivo da 'exportação' é fazer com que as variáveis "estejam no ambiente de comandos executados posteriormente", sejam esses subconjuntos ou subprocessos. Uma implementação ingênua seria simplesmente colocar a variável no ambiente do shell, mas isso impossibilitaria a implementação export -p.
Observe que isso não é inteiramente verdade. Em bash, a exportação realmente adiciona a variável ao ambiente do shell atual, mas esse não é o caso dash. Parece-me que adicionar a variável ao ambiente do shell atual é a maneira mais simples de implementar a semântica export, mas esse comportamento não é obrigatório.
William Pursell
7
Não tenho certeza do que dashtem a ver com isso. O pôster original estava perguntando especificamente sobre bash.
Starfish
14
A pergunta está marcada, bashmas se aplica igualmente a qualquer variante de casca de bourne. Ser excessivamente específico e fornecer respostas que se aplicam apenas a bashum grande mal.
William Pursell
12
bashé o jQuery do shell.
Potherca
2
export makes the variable available to subshells, and that is correctEste é um uso muito confuso da terminologia. Subshells não precisam exportherdar variáveis. Subprocessos fazem.
Amit Naidu
62
Já foi dito que não é necessário exportar no bash ao gerar sub-conchas, enquanto outros disseram exatamente o oposto. É importante notar a diferença entre subshells (aqueles que são criados por (), ``, $()ou loops) e subprocessos (processos que são chamados pelo nome, por exemplo, um literal bashaparecendo em seu script).
Os subconjuntos terão acesso a todas as variáveis do pai, independentemente do estado exportado.
Sub processos será única ver as variáveis exportadas.
O que é comum nessas duas construções é que nenhuma delas pode passar variáveis de volta para o shell pai.
Há mais uma fonte de confusão: alguns pensam que subprocessos 'bifurcados' são os que não veem variáveis não exportadas. Normalmente, fork () s é imediatamente seguido por exec () s, e é por isso que parece que o fork () é a coisa a procurar, enquanto na verdade é o exec (). Você pode executar comandos sem fork () primeiro com o execcomando, e os processos iniciados por esse método também não terão acesso a variáveis não exportadas:
Eu nunca vi um loop que (por si só) criou um subshell; OTOH que um pipeline faz (sempre para peças diferentes da última, às vezes para a última, dependendo do shell, versão e opções). Backgrounding ( &) também cria um subshell.
Dave_thompson_085
E esses var=asdf bash -c 'echo $var'ou var=asdf exec bash -c 'echo $var'? A saída é asdf. A ;diferença faz se colocada após a definição da variável. Qual seria a explicação? Parece que var(sem ;) o subprocesso gerado de alguma forma, devido ao shell de origem não ter nada a ver com isso. echo $varimprime nada se executado na segunda linha. Mas um alinhado var=asdf bash -c 'echo $var'; echo $vardá asdf\nasdf.
4xy 13/07/19
31
export NAME=value para configurações e variáveis que têm significado para um subprocesso.
NAME=value para variáveis temporárias ou de loop privadas ao processo atual do shell.
Mais detalhadamente, exportmarca o nome da variável no ambiente que copia para um subprocesso e seus subprocessos na criação. Nenhum nome ou valor é copiado novamente do subprocesso.
Um erro comum é colocar um espaço ao redor do sinal de igual:
$ export FOO ="bar"
bash: export:`=': not a valid identifier
Somente a variável exportada ( B) é vista pelo subprocesso:
$ A="Alice"; export B="Bob"; echo "echo A is \$A. B is \$B"| bash
A is . B is Bob
Alterações no subprocesso não alteram o shell principal:
$ export B="Bob"; echo 'B="Banana"'| bash; echo $B
Bob
As variáveis marcadas para exportação têm valores copiados quando o subprocesso é criado:
$ 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
Subprocess1 has B=BobSubprocess2 has B=Banana[1]+Done echo '(sleep 30; echo "Subprocess 1 has B=$B")'| bash
Somente variáveis exportadas se tornam parte do ambiente ( man environ):
Note-se que você pode exportar uma variável e depois alterar o valor. O valor alterado da variável estará disponível para processos filho. Depois que a exportação for definida para uma variável, você deve fazer export -n <var>para remover a propriedade
Obrigado, esta é exatamente a informação que eu estava procurando, porque vi um script que usava variáveis de ambiente e depois as "reexportou" com um novo valor, e fiquei imaginando se era necessário.
Mike Lippert
8
Como você já deve saber, o UNIX permite que os processos tenham um conjunto de variáveis de ambiente, que são pares de chave / valor, sendo chave e valor como cadeias. O sistema operacional é responsável por manter esses pares para cada processo separadamente.
O programa pode acessar suas variáveis de ambiente através desta API UNIX:
char *getenv(const char *name);
int setenv(const char *name, const char *value, int override);
int unsetenv(const char *name);
Os processos também herdam variáveis de ambiente dos processos pai. O sistema operacional é responsável por criar uma cópia de todos os "envares" no momento em que o processo filho é criado.
O Bash , entre outros shells, é capaz de definir suas variáveis de ambiente mediante solicitação do usuário. É para isso que exportexiste.
exporté um comando do Bash para definir a variável de ambiente para o Bash. Todas as variáveis definidas com este comando seriam herdadas por todos os processos que esse Bash criaria.
Outro tipo de variável no Bash é a variável interna. Como o Bash não é apenas um shell interativo, ele é, de fato, um interpretador de script, pois qualquer outro intérprete (por exemplo, Python) é capaz de manter seu próprio conjunto de variáveis. Deve-se mencionar que o Bash (diferente do Python) suporta apenas variáveis de string.
A notação para definir variáveis Bash é name=value. Essas variáveis permanecem no Bash e não têm nada a ver com variáveis de ambiente mantidas pelo sistema operacional.
Também vale ressaltar que, de acordo com o manual de referência do Bash:
O ambiente para qualquer comando ou função simples pode ser aumentado temporariamente, prefixando-o com designações de parâmetros, conforme descrito em Parâmetros do Shell . Essas instruções de atribuição afetam apenas o ambiente visto por esse comando.
Para resumir:
exporté usado para definir variável de ambiente no sistema operacional. Essa variável estará disponível para todos os processos filhos criados pelo processo Bash atual para sempre.
A notação de variável bash (nome = valor) é usada para definir variáveis locais disponíveis apenas para o processo atual de bash
A notação de variável bash que prefixa outro comando cria a variável de ambiente apenas para o escopo desse comando.
O bash vars não suporta tantos tipos quanto o Python, mas possui string, número inteiro e dois tipos de array ('indexado' / tradicional e 'associativo', que é semelhante ao awk array, perl hash ou Python dict). Outras conchas variam; única string é portátil .
Dave_thompson_085
7
A resposta aceita implica isso, mas eu gostaria de tornar explícita a conexão com os shell builtins:
Como já mencionado, exportdisponibilizará uma variável para o shell e os filhos. Se nãoexport for usada, a variável estará disponível apenas no shell, e somente os recursos internos do shell poderão acessá-lo.
Isso é,
tango=3
env | grep tango # prints nothing, since env is a child processset| grep tango # prints tango=3 - "type set" shows `set` is a shell builtin
Dois dos criadores do UNIX, Brian Kernighan e Rob Pike, explicam isso em seu livro "O ambiente de programação UNIX". Google para o título e você encontrará facilmente uma versão em pdf.
Eles abordam variáveis de shell na seção 3.6 e focam no uso do exportcomando no final dessa seção:
Quando você deseja tornar acessível o valor de uma variável em subconchas, o comando de exportação do shell deve ser usado. (Você pode pensar por que não há como exportar o valor de uma variável de um sub-shell para seu pai).
Por padrão, as variáveis criadas em um script estão disponíveis apenas para o shell atual; processos filhos (sub-shells) não terão acesso a valores que foram definidos ou modificados. Permitir que os processos filhos vejam os valores requer o uso do comando de exportação.
Embora não seja mencionado explicitamente na discussão, NÃO é necessário usar a exportação ao gerar um subshell a partir do bash, pois todas as variáveis são copiadas no processo filho.
export name=value
não é portátil. Dependendo do que exatamente você deseja, tentename=value; export name
uma solução portátil.Respostas:
export
torna a variável disponível para subprocessos.Isso é,
significa que o nome da variável está disponível para qualquer processo executado a partir desse processo de shell. Se você deseja que um processo faça uso dessa variável, use
export
e execute o processo nesse shell.significa que o escopo da variável é restrito ao shell e não está disponível para nenhum outro processo. Você usaria isso para (digamos) variáveis de loop, variáveis temporárias etc.
É importante observar que a exportação de uma variável não a torna disponível para processos-pai. Ou seja, especificar e exportar uma variável em um processo gerado não a torna disponível no processo que a iniciou.
fonte
name=value command
não fazer a variável disponível no sub-processocommand
.Para ilustrar o que as outras respostas estão dizendo:
fonte
al$ foobar="Whatever" bash
Outros responderam que a exportação disponibiliza a variável para subshells, e isso é correto, mas apenas um efeito colateral. Quando você exporta uma variável, ela a coloca no ambiente do shell atual (ou seja, o shell chama
putenv(3)
ousetenv(3)
).O ambiente de um processo é herdado entre exec, tornando a variável visível em subshells.
Editar (com perspectiva de 5 anos): esta é uma resposta boba. O objetivo da 'exportação' é fazer com que as variáveis "estejam no ambiente de comandos executados posteriormente", sejam esses subconjuntos ou subprocessos. Uma implementação ingênua seria simplesmente colocar a variável no ambiente do shell, mas isso impossibilitaria a implementação
export -p
.fonte
bash
, a exportação realmente adiciona a variável ao ambiente do shell atual, mas esse não é o casodash
. Parece-me que adicionar a variável ao ambiente do shell atual é a maneira mais simples de implementar a semânticaexport
, mas esse comportamento não é obrigatório.dash
tem a ver com isso. O pôster original estava perguntando especificamente sobrebash
.bash
mas se aplica igualmente a qualquer variante de casca de bourne. Ser excessivamente específico e fornecer respostas que se aplicam apenas abash
um grande mal.bash
é o jQuery do shell.export makes the variable available to subshells, and that is correct
Este é um uso muito confuso da terminologia. Subshells não precisamexport
herdar variáveis. Subprocessos fazem.Já foi dito que não é necessário exportar no bash ao gerar sub-conchas, enquanto outros disseram exatamente o oposto. É importante notar a diferença entre subshells (aqueles que são criados por
()
,``
,$()
ou loops) e subprocessos (processos que são chamados pelo nome, por exemplo, um literalbash
aparecendo em seu script).O que é comum nessas duas construções é que nenhuma delas pode passar variáveis de volta para o shell pai.
Há mais uma fonte de confusão: alguns pensam que subprocessos 'bifurcados' são os que não veem variáveis não exportadas. Normalmente, fork () s é imediatamente seguido por exec () s, e é por isso que parece que o fork () é a coisa a procurar, enquanto na verdade é o exec (). Você pode executar comandos sem fork () primeiro com o
exec
comando, e os processos iniciados por esse método também não terão acesso a variáveis não exportadas:Observe que
parent:
desta vez não vemos a linha, porque substituímos o shell pai peloexec
comando, então não há mais nada para executar esse comando.fonte
&
) também cria um subshell.var=asdf bash -c 'echo $var'
ouvar=asdf exec bash -c 'echo $var'
? A saída éasdf
. A;
diferença faz se colocada após a definição da variável. Qual seria a explicação? Parece quevar
(sem;
) o subprocesso gerado de alguma forma, devido ao shell de origem não ter nada a ver com isso.echo $var
imprime nada se executado na segunda linha. Mas um alinhadovar=asdf bash -c 'echo $var'; echo $var
dáasdf\nasdf
.export NAME=value
para configurações e variáveis que têm significado para um subprocesso.NAME=value
para variáveis temporárias ou de loop privadas ao processo atual do shell.Mais detalhadamente,
export
marca o nome da variável no ambiente que copia para um subprocesso e seus subprocessos na criação. Nenhum nome ou valor é copiado novamente do subprocesso.Um erro comum é colocar um espaço ao redor do sinal de igual:
Somente a variável exportada (
B
) é vista pelo subprocesso:Alterações no subprocesso não alteram o shell principal:
As variáveis marcadas para exportação têm valores copiados quando o subprocesso é criado:
Somente variáveis exportadas se tornam parte do ambiente (
man environ
):Então, agora deve estar tão claro quanto o sol do verão! Agradecimentos a Brain Agnew, alexp e William Prusell.
fonte
export
tornará a variável disponível para todos os shells bifurcados no shell atual.fonte
Note-se que você pode exportar uma variável e depois alterar o valor. O valor alterado da variável estará disponível para processos filho. Depois que a exportação for definida para uma variável, você deve fazer
export -n <var>
para remover a propriedadefonte
Como você já deve saber, o UNIX permite que os processos tenham um conjunto de variáveis de ambiente, que são pares de chave / valor, sendo chave e valor como cadeias. O sistema operacional é responsável por manter esses pares para cada processo separadamente.
O programa pode acessar suas variáveis de ambiente através desta API UNIX:
char *getenv(const char *name);
int setenv(const char *name, const char *value, int override);
int unsetenv(const char *name);
Os processos também herdam variáveis de ambiente dos processos pai. O sistema operacional é responsável por criar uma cópia de todos os "envares" no momento em que o processo filho é criado.
O Bash , entre outros shells, é capaz de definir suas variáveis de ambiente mediante solicitação do usuário. É para isso que
export
existe.export
é um comando do Bash para definir a variável de ambiente para o Bash. Todas as variáveis definidas com este comando seriam herdadas por todos os processos que esse Bash criaria.Mais sobre Meio ambiente em Bash
Outro tipo de variável no Bash é a variável interna. Como o Bash não é apenas um shell interativo, ele é, de fato, um interpretador de script, pois qualquer outro intérprete (por exemplo, Python) é capaz de manter seu próprio conjunto de variáveis. Deve-se mencionar que o Bash (diferente do Python) suporta apenas variáveis de string.
A notação para definir variáveis Bash é
name=value
. Essas variáveis permanecem no Bash e não têm nada a ver com variáveis de ambiente mantidas pelo sistema operacional.Mais sobre parâmetros de shell (incluindo variáveis)
Também vale ressaltar que, de acordo com o manual de referência do Bash:
Para resumir:
export
é usado para definir variável de ambiente no sistema operacional. Essa variável estará disponível para todos os processos filhos criados pelo processo Bash atual para sempre.fonte
A resposta aceita implica isso, mas eu gostaria de tornar explícita a conexão com os shell builtins:
Como já mencionado,
export
disponibilizará uma variável para o shell e os filhos. Se nãoexport
for usada, a variável estará disponível apenas no shell, e somente os recursos internos do shell poderão acessá-lo.Isso é,
fonte
Aqui está outro exemplo:
Somente usando a exportação VARTEST, o valor de VARTEST está disponível no sudo bash -c '...'!
Para mais exemplos, consulte:
http://mywiki.wooledge.org/SubShell
bash-hackers.org/wiki/doku.php/scripting/processtree
fonte
Dois dos criadores do UNIX, Brian Kernighan e Rob Pike, explicam isso em seu livro "O ambiente de programação UNIX". Google para o título e você encontrará facilmente uma versão em pdf.
Eles abordam variáveis de shell na seção 3.6 e focam no uso do
export
comando no final dessa seção:fonte
Apenas para mostrar a diferença entre uma variável exportada que está no ambiente (env) e uma variável não exportada que não está no ambiente:
Se eu fizer isso:
somente $ OURNAME aparece no ambiente. A variável $ MYNAME não está no ambiente.
mas a variável $ MYNAME existe no shell
fonte
Por padrão, as variáveis criadas em um script estão disponíveis apenas para o shell atual; processos filhos (sub-shells) não terão acesso a valores que foram definidos ou modificados. Permitir que os processos filhos vejam os valores requer o uso do comando de exportação.
fonte
Embora não seja mencionado explicitamente na discussão, NÃO é necessário usar a exportação ao gerar um subshell a partir do bash, pois todas as variáveis são copiadas no processo filho.
fonte