Estou interessado em definir variáveis ambientais de uma instância de shell de outra. Então eu decidi fazer alguma pesquisa. Depois de ler um número de perguntas sobre isso eu decidi testá-lo.
Eu criei duas conchas A e B (PID 420), ambas em execução zsh
. A partir do shell, AI executou o seguinte.
sudo gdb -p 420
(gdb) call setenv("FOO", "bar", 1)
(gdb) detach
No shell B, quando executo env
, posso ver que a variável FOO está realmente definida com um valor de bar. Isso me faz pensar que o FOO foi inicializado com sucesso no ambiente do shell B. No entanto, se eu tentar imprimir o FOO, recebo uma linha vazia, indicando que ela não está definida. Para mim, parece que há uma contradição aqui.
Isso foi testado no meu próprio sistema Arch GNU / Linux e em uma VM do Ubuntu. Também testei isso em bash
que a variável nem apareceu em env. Isso, apesar de decepcionante para mim, faz sentido se o shell armazena em cache uma cópia de seu ambiente no momento da desova e a utiliza apenas (o que foi sugerido em uma das perguntas vinculadas). Isso ainda não responde por que zsh
pode ver a variável.
Por que a saída de echo $FOO
vazia?
EDITAR
Após a entrada nos comentários, decidi fazer um pouco mais de teste. Os resultados podem ser vistos nas tabelas abaixo. Na primeira coluna está o shell no qual a FOO
variável foi injetada. A primeira linha contém o comando cuja saída pode ser vista abaixo dela. A variável FOO
foi injectado usando: sudo gdb -p 420 -batch -ex 'call setenv("FOO", "bar", 1)'
. Os comandos específicos do zsh: zsh -c '...'
também foram testados usando o bash. Os resultados foram idênticos, sua saída foi omitida por brevidade.
Arch GNU / Linux, zsh 5.3.1, bash 4.4.12 (1)
| | env | grep FOO | echo $FOO | zsh -c 'env | grep FOO' | zsh -c 'echo $FOO' | After export FOO |
|------|------------------|-----------|---------------------------|----------------------|-----------------------------------|
| zsh | FOO=bar | | FOO=bar | bar | No Change |
| bash | | bar | | | Value of FOO visible in all tests |
Ubuntu 16.04.2 LTS, zsh 5.1.1, bash 4.3.48 (1)
| | env | grep FOO | echo $FOO | zsh -c 'env | grep FOO' | zsh -c 'echo $FOO' | After export FOO |
|------|------------------|-----------|---------------------------|----------------------|-----------------------------------|
| zsh | FOO=bar | | FOO=bar | bar | No Change |
| bash | | bar | | | Value of FOO visible in all tests |
O exposto acima parece implicar que os resultados são agnósticos na distribuição. Isso não me diz muito mais do que zsh
e bash
lida com a configuração de variáveis de maneira diferente. Além disso, export FOO
possui um comportamento muito diferente nesse contexto, dependendo do shell. Esperançosamente, esses testes podem deixar algo claro para outra pessoa.
env
) veem o ambiente modificado.
zsh
no GDB não a torna visível como uma variável de shell, mas faz com que ela seja passada para processos filho (como você observou), ao definir um para bash
o torna visível como uma variável de shell, mas não faz com que ela seja passada para processos filhos! Parece que o zsh e o bash usam estratégias diferentes para gerenciar variáveis, com o zsh que rastreia variáveis que não são de ambiente e o bash armazena tudo em seu ambiente, que é higienizado ao iniciar um filho (sem sub-shell).
export FOO
em bash
?
zsh -c 'echo $FOO'
(use aspas simples!)? Você pode ver isso então?