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?
shell
environment-variables
echo
ashleysmithgpu
fonte
fonte
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
vai funcionar.
export
fará com que a variável apareça no ambiente de comandos executados subseqüentemente (veja como isso funciona no bashhelp export
). Se você só precisa que a variável apareça no ambiente de um comando, use o que você tentou, ou seja:fonte
$TEST
antes de a linha de comando ser executada. Uma vez queecho
está em execução (observe também queecho
normalmente 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 $TEST
não informaecho
a saída do conteúdo da variávelTEST
de seu ambiente. Ele diz ao shell para executarecho
com argumento sendo o que está atualmente na variável chamadaTEST
- 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 …'
). Comoecho "$var"
está entre aspas simples, toda a cadeia de caracteres é passada para osh -c
shell new ( ) sem ser interpretada pelo shell interativo externo. ... (continua)sh -c
shell 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
Você está passando a
var=value
string para o ambiente que o eco recebe. No entanto,echo
nã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
Isso teria sido outra questão. Aqui, estamos passando
var=value
para osh
comando esh
, 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 avar
variável de ambientesh
recebida seja convertida em uma$var
variável e, quando a expandir nessaecho
linha de comando, ela se tornaráecho value
. Como o ambiente é herdado por padrão,echo
também receberávar=value
em seu ambiente (ou seria se fosse executado), mas, novamente,echo
nã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):
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":
Com o zsh, você pode usar funções embutidas:
ou:
Com bash e zsh (mas não ash, pdksh ou AT&T ksh), esse truque também funciona:
Uma variante que funciona em mais algumas conchas (
dash
,mksh
,yash
), mas nãozsh
(a menos que emsh
/ksh
emulação):(usar
command
na frente de um built-in especial (aquieval
) em shells POSIX remove sua especialidade (aqui as atribuições de variáveis delas permanecem em vigor após o retorno))fonte
Você está fazendo isso corretamente, mas a sintaxe do bash é fácil de interpretar mal: você pode pensar que isso
echo $TEST
fazecho
com que a busca sejaTEST
env var e, em seguida, imprima-a, não é. Tão dadoentão
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
Ele cria os vars temporários definidos antes do comando, para salvar o valor atual de
TEST
e substituí-lo por 456; a linha de comando é agoraEle 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:
fonte
printenv
útil para teste / prova de conceito (se comporta como um script, em oposição aecho
)Você pode fazer isso funcionar usando:
fonte
TEST=foo
está sendo executado como uma instrução separada - não é apenas configurada no contexto deecho
.