Se eu correr
export TEST=foo
echo $TEST
Ele produz foo.
Se eu correr
TEST=foo echo $TEST
Isso não. Como posso obter essa funcionalidade sem usar um script de exportação ou?
Se eu correr
export TEST=foo
echo $TEST
Ele produz foo.
Se eu correr
TEST=foo echo $TEST
Isso não. Como posso obter essa funcionalidade sem usar um script de exportação ou?
Respostas:
Isso ocorre porque o shell expande a variável na linha de comando antes de realmente executar o comando e nesse momento a variável não existe. Se você usar
TEST=foo; echo $TEST
vai funcionar.
exportfará com que a variável apareça no ambiente de comandos executados subseqüentemente (veja como isso funciona no bash help export). Se você só precisa que a variável apareça no ambiente de um comando, use o que você tentou, ou seja:
TEST=foo your-application
$TESTantes de a linha de comando ser executada. Uma vez que echoestá em execução (observe também que echonormalmente será traduzido para o comando interno do shell e não para /bin/echo), ele vê a variável definida em seu ambiente. No entanto, echo $TESTnão informa echoa saída do conteúdo da variável TESTde seu ambiente. Ele diz ao shell para executar echocom argumento sendo o que está atualmente na variável chamada TEST- e essas são duas coisas muito diferentes.
var=value sh -c 'echo "$var"'?
"… $var …") , mas não dentro de aspas simples (por exemplo, '… $var …'). Como echo "$var"está entre aspas simples, toda a cadeia de caracteres é passada para o sh -cshell new ( ) sem ser interpretada pelo shell interativo externo. ... (continua)
sh -cshell filho ( ).
Eu suspeito que você deseja que variáveis de shell tenham um escopo limitado, em vez de variáveis de ambiente. Variáveis de ambiente são uma lista de cadeias de caracteres passadas para comandos quando são executadas .
No
var=value echo whatever
Você está passando a var=valuestring para o ambiente que o eco recebe. No entanto, echonão faz nada com sua lista de ambientes e, de qualquer maneira, na maioria dos shells, echoé incorporado e, portanto, não é executado .
Se você tivesse escrito
var=value sh -c 'echo "$var"'
Isso teria sido outra questão. Aqui, estamos passando var=valuepara o shcomando e sh, por acaso, usamos seu ambiente. Os shells convertem cada uma das variáveis que recebem de seu ambiente em uma variável de shell, para que a varvariável de ambiente shrecebida seja convertida em uma $varvariável e, quando a expandir nessa echolinha de comando, ela se tornará echo value. Como o ambiente é herdado por padrão, echotambém receberá var=valueem seu ambiente (ou seria se fosse executado), mas, novamente, echonão se importa com o ambiente.
Agora, se eu suspeito, o que você deseja é limitar o escopo das variáveis do shell, existem várias abordagens possíveis.
Portably (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), portanto, qualquer variável declarada lá afetará apenas esse sub-shell, portanto, espero que o código acima produza "1: value" e "2:" ou "2: o que-var-foi-definido-antes".
Com a maioria dos shells Bourne, você pode usar funções e o built-in "local":
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 bash e 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 algumas conchas ( dash, mksh, yash), mas não zsh(a menos que em sh/ kshemulação):
var=value command eval 'echo "1: $var"'; echo "2: $var"
(usar commandna frente de um built-in especial (aqui eval) em shells POSIX remove sua especialidade (aqui as atribuições de variáveis delas permanecem em vigor após o retorno))
Você está fazendo isso corretamente, mas a sintaxe do bash é fácil de interpretar mal: você pode pensar que isso echo $TESTfaz echocom que a busca seja TESTenv var e, em seguida, imprima-a, não é. Tão dado
export TEST=123
então
TEST=456 echo $TEST
envolve a seguinte sequência:
O shell analisa toda a linha de comandos e executa todas as substituições de variáveis, para que a linha de comandos se torne
TEST=456 echo 123Ele cria os vars temporários definidos antes do comando, para salvar o valor atual de TESTe substituí-lo por 456; a linha de comando é agora
echo 123Ele executa o comando restante, que nesse caso imprime 123 no stdout (portanto, o comando shell que permanece permanece nem usa o valor temp de TEST)
Restaura o valor de TEST
Use printenv, pois não envolve substituição de variável:
>> 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
>>
printenvútil para teste / prova de conceito (se comporta como um script, em oposição a echo)
Você pode fazer isso funcionar usando:
TEST=foo && echo $TEST
TEST=fooestá sendo executado como uma instrução separada - não é apenas configurada no contexto de echo.