Como eu configuro uma variável de ambiente na linha de comando e faço com que ela apareça nos comandos?

127

Se eu correr

export TEST=foo
echo $TEST

Produz foo.

Se eu correr

TEST=foo echo $TEST

Não. Como posso obter essa funcionalidade sem usar exportação ou um script?

    
por ashleysmithgpu 23.11.2012 / 11:17

4 respostas

146

Isso ocorre porque o shell expande a variável na linha de comando antes de , na verdade, executa o comando e, nesse momento, a variável não existe. Se você usa

TEST=foo; echo $TEST

funcionará.

export fará a variável aparecer no ambiente de comandos executados subseqüentemente (para saber como isso funciona no bash, consulte help export ). Se você precisar que a variável apareça no ambiente de um comando, use o que você tentou, por exemplo:

TEST=foo your-application
    
por 23.11.2012 / 11:37
33

Eu suspeito que você queira que as variáveis shell tenham um escopo limitado, em vez de variáveis de ambiente. Variáveis de ambiente são uma lista de strings passadas para comandos quando são executadas .

Em

var=value echo whatever

Você está passando a string var=value para o ambiente que o echo recebe. No entanto, echo não faz nada com sua lista de ambientes e, de qualquer forma, na maioria dos shells, echo é construído e, portanto, não executado .

Se você tivesse escrito

var=value sh -c 'echo "$var"'

Isso teria sido outro assunto. Aqui, estamos passando var=value para o comando sh e sh por acaso usa seu ambiente. Shells convertem cada uma das variáveis que recebem de seu ambiente para uma variável de shell, portanto a var variável de ambiente sh recebe será convertida em uma variável $var e, quando expandida, na linha de comando echo , que se tornará echo value . Como o ambiente é herdado por padrão, echo também receberá var=value em seu ambiente (ou seria se ele fosse executado), mas novamente, echo não se importa com o ambiente.

Agora, se, como suspeito, o que você quer é limitar o escopo das variáveis do shell, existem várias abordagens possíveis.

Portável (Bourne e POSIX):

(var=value; echo "1: $var"); echo "2: $var"

O (...) acima inicia um sub-shell (um novo processo de shell na maioria dos shells), então qualquer variável declarada lá afetará apenas o sub-shell, então eu esperaria que o código acima fosse "1 : valor "e" 2: "ou" 2: whatever-var-foi-definido-para-antes ".

Com a maioria dos shells parecidos com Bourne, você pode usar funções e o "local" interno:

f() {
  local var
  var=value
  echo "1: $var"
}
f
echo "2: $var"

Com o zsh, você pode usar funções embutidas:

(){ local var=value; echo "1: $var"; }; echo "2: $var"

ou:

function { local var=value; echo "1: $var"; }; echo "2: $var"

Com o bash e o zsh (mas não ash, pdksh ou AT & T ksh), esse truque também funciona:

var=value eval 'echo "1: $var"'; echo "2: $var"

Uma variante que funciona em mais alguns shells ( dash , mksh , yash ), mas não zsh (a menos que em sh / ksh emulation):

var=value command eval 'echo "1: $var"'; echo "2: $var"

(usar command na frente de um especial embutido (aqui eval ) em POSIX shells remove seu especialismo (aqui as designações de variáveis delas permanecem válidas depois que retornarem))

    
por 23.11.2012 / 12:31
5

Você pode fazer isso funcionar usando:

TEST=foo && echo $TEST
    
por 23.11.2012 / 11:23
0

Você está fazendo isso corretamente, mas a sintaxe do bash é fácil de interpretar incorretamente: você pode pensar que echo $TEST faz com que echo obtenha TEST env var e imprima, não. Em vez disso, o shell analisa toda a linha de comando e executa todas as substituições de variáveis; Então ele cria o temp vars ( TEST no seu caso), então executa o comando que vem depois, com aqueles vars no seu env.

Tente isto:

>> export TEST=123
>> printenv TEST
123
>> TEST=456 printenv TEST
456
>> printenv TEST && TEST=456 printenv TEST && TEST=789 printenv TEST && printenv TEST
123
456
789
123
>>
    
por 05.04.2018 / 02:13