Por que essa variável de ambiente não está configurada?

1
  1. Quando um shell executa um executável externo como um comando, podemos passar variáveis de ambiente no executável.

    $ var=3 /bin/echo '$var'
    
    $ var=3 bash -c "/bin/echo '$var'"
    

    ambos não produzem nada.

  2. Quando um programa é executado por exec , quero ver se o ambiente variável também funciona:

    $ bash
    $ unset var; 
    $ var=3 exec /bin/echo '$var'
    $var
    $ exec var=3 /bin/echo '$var'
    bash: exec: var=3: not found
    

Para evitar a expansão de variáveis, uso aspas simples em torno de $var . A proteção parece um pouco demais.

Por que essa variável de ambiente não está configurada nos casos acima?

Posso fazer com que variáveis de ambiente funcionem para um programa executado por exec ?

Obrigado.

    
por Tim 31.07.2017 / 16:27

2 respostas

3
  • Todos os seus problemas estão relacionados à cotação, não ao ambiente.

    1. Ambiente para um comando.

      When a shell runs an external executable as a command, we can pass environment variables into the executable.

    Sim, essa é uma maneira de definir variáveis de ambiente para um comando, externo ou de outra forma.

    Mas o que está faltando nesta linha [a] :

    $ var=3 /bin/echo "$var"
    

    É que o shell expande a variável ao construir os argumentos e, se a variável var não estiver definida no shell que inicia o comando, isso é o que é realmente executado:

    $ var=3 /bin/echo ""
    

    Para realmente ver a presente expansão do shell, execute isto:

    $ var=RunningShell ;   var=3 /bin/echo "$var"
    RunningShell
    

    Uma maneira (muitas vezes insegura) de atrasar a avaliação da variável é:

    $ var=3 eval /bin/echo '"$var"'
    3
    

    No segundo exemplo, você tem as citações trocadas:

    $ var=3 bash -c "/bin/echo '$var'"
    

    Imprime nada quando a linha de comando atual se torna:

    $ var=3 bash -c "/bin/echo ''"
    

    Como o valor da variável (não definida) $ var é expandido. Você provavelmente quis dizer isso:

    $ var=thisis3 bash -c '/bin/echo "$var"'
    thisis3
    

    Nesse caso, as aspas simples impedem a expansão da variável pelo shell de execução, deixando a expansão para o shell executado ( bash -c ).

    • Use env para realmente ver o ambiente.

      1. Quando um programa é executado por exec, quero ver se a variável de ambiente também funciona:

    Não execute em seu shell atual, pois ele fechará o shell em execução.
    Você pode fazer isso para evitar fechar o shell em execução:

    $ var=3 exec /bin/echo \$var | cat
    $var
    

    Como o shell fechado será aquele que seria fechado de qualquer maneira, o primeiro sub-shell de um pipe.

    Mas isso não mostrará o valor de var no ambiente. Para ver variáveis no ambiente, use o comando para ver o ambiente:

    $ var=3 env | grep var
    var=3
    

[a] O comando que você escreveu teve backquotes ' , alterando-as para aspas simples evitará a expansão da variável e imprimirá $var .:

$ var=3 /bin/echo '$var'
$var
    
por 31.07.2017 / 22:42
5

Lembre-se de que a expansão de parâmetros não ocorre magicamente. Você precisa de um shell para fazer isso por você.

var=3 /bin/echo '$var'

Não sei ao certo o que você está tentando fazer com esse, as carreiras de retorno não são apropriadas aqui (elas executam um comando e são substituídas por sua saída).

var=3 bash -c "/bin/echo '$var'"

não funciona porque a expansão do parâmetro ocorre antes da atribuição, portanto, o shell atual altera "/bin/echo '$var'" para /bin/echo '' (assumindo que var é indefinido) e o shell filho é executado com

/bin/echo ''

Tente

var=3 bash -c 'echo $var'

em vez disso: as aspas simples aqui protegem o argumento do shell atual e o novo shell é executado com

echo $var

que será processado como você espera.

Em seu segundo ponto, meu comentário inicial ainda se aplica. Se você quiser brincar com o ambiente e ver o que acontece, execute env e filtre sua saída:

var=3 env | grep var
var=3 exec env | grep var
    
por 31.07.2017 / 16:39