Escopo de uma variável exportada no shell

3

Digamos que eu tenha um script para o qual exportei uma variável como visto abaixo:

#!/bin/bash
foo(){
    eval export one=1
}
foo1(){
    eval export two=2
}
(foo)
foo1
echo "one=$one"
echo "two=$two"

No entanto, recebi a seguinte saída:

root@centos1:~>/tmp/test.sh
one=
two=2 

Por que motivo não consigo ver o valor de $one e posso ver $two ?

    
por Bhagyesh Dudhediya 11.05.2016 / 12:54

2 respostas

4

As variáveis globais vivem do momento em que são configuradas até o momento em que são desativadas ou o processo é encerrado. Variáveis globais (nem locais) não são herdadas por processos filhos não relacionados (se o processo filho for um fork (um subshell), ele obtém uma cópia de tudo - exportado ou não).

Variáveis globais exportadas são como variáveis globais, mas também são automaticamente herdadas (como parte do ambiente de processo) por processos filhos, mesmo que não relacionados. (Com as exportações, você pode passar uma variável como CXXFLAGS para um processo como make , que definitivamente não é uma subcamada de seu shell, e todo processo que make gera também obterá essa variável também .)

No seu exemplo, () cria uma subshell, que obtém uma cópia de tudo. O comando foo modifica a subshell adicionando uma variável exportada e, em seguida, a subshell termina sem nunca utilizar a variável exportada (nenhum neto a herdou). Agora, nenhuma informação viaja implicitamente de processos filhos para processos pai. O que as crianças fazem em seu ambiente não afeta seus pais. Essa é a razão pela qual sua variável one não está definida.

BTW, esses eval s são eval desnecessários neste contexto.

    
por 11.05.2016 / 13:10
0

Colocar um comando entre ( ) resultará no comando estar em um sub shell.

Isso pode ser útil se um for canalizar ou sair.

( date ; cmd1 ; cmd2 ) | grep ...

resultará da concatenação do primeiro 3 comando e da saída para grep (neste caso).

Você pode considerar {} , bem como ler a página man do bash

   (list) list is executed in a subshell environment (see  COMMAND  EXECUTION  ENVIRONMENT  
        below).   Variable  assignments  and  builtin commands that affect the 
        shell's environment do not remain in effect after the command completes.  
        The return status is the exit status of list.

   { list; }
          list is simply executed in the current shell environment. list must be 
          terminated with a newline or semicolon.   This is known as a group
          command.  The return status is the exit status of list.
          Note  that unlike the metacharacters ( and ), { and } are reserved 
          words and must occur where  a  reseved word  is  permitted  to be recognized.  
          Since they do not cause a word break, they must be separated
          from list by whitespace or another shell metacharacter.
    
por 11.05.2016 / 13:15