Quando usar um ponto e vírgula entre variáveis ​​de ambiente e um comando


14

Alguém pode explicar por que o ponto-e-vírgula é necessário para LANGque seja visto como atualizado pelo bash?

Não funciona:

> LANG=Ja_JP bash -c "echo $LANG"
en_US

Trabalho:

> LANG=Ja_JP ; bash -c "echo $LANG"
Ja_JP

Estou trabalhando com o bash 4.1.10 no linux e a mesma versão no cygwin

Respostas:


23

Parâmetros e outros tipos de expansões são executados quando o comando é lido, antes de ser executado.

A primeira versão,, LANG=Ja_JP bash -c "echo $LANG"é um único comando. Depois de analisado como tal, $LANGé expandido para en_USantes de qualquer coisa ser executada. Uma vez que bashestá terminado o processamento da entrada, ele bifurca um processo, acrescenta LANG=Ja_JPao ambiente como esperado, e então executa bash -c echo en_US.

Você pode impedir a expansão com aspas simples, ou seja, LANG=Ja_JP bash -c 'echo $LANG'saídas Ja_JP.

Observe que, quando você tem uma atribuição de variável como parte de um comando, a atribuição afeta apenas o ambiente desse comando e não o do seu shell.

A segunda versão, LANG=Ja_JP; bash -c "echo $LANG"na verdade , são dois comandos separados executados em sequência. A primeira é uma atribuição simples de variável sem um comando, portanto afeta o shell atual.

Assim, seus dois trechos são fundamentalmente diferentes, apesar da distinção superficial de um único ;.

Completamente fora do tópico, mas recomendo anexar a .UTF-8quando definir LANG. Atualmente, não há uma boa razão para não usar o Unicode no século XXI.


Ótima resposta - obrigado! Em relação à adição de UTF-8. Estou tentando testar a manipulação de localidade de um aplicativo que precisa funcionar em várias plataformas, algumas das quais bastante antigas. Entre diferenças como essa (que felizmente você explicou) e diferenças no linux e cygwin, estou prestes a me jogar debaixo de um ônibus!
Richard Corden

5

VAR=value; somecommand é equivalente a

VAR=value
somecommand

Estes são comandos não relacionados executados um após o outro. O primeiro comando atribui um valor à variável do shell VAR. A menos que VARjá seja uma variável de ambiente, não seja exportada para o ambiente, ela permanece interna no shell. Uma declaração export VARseria exportada VARpara o ambiente.

VAR=value somecommandé uma sintaxe diferente. A atribuição VAR=valueé para o ambiente, mas essa atribuição é feita apenas no ambiente de execução de somecommand, não para a execução subsequente do shell.

A título de exemplo:

# Assume neither VAR1 nor VAR2 is in the environment
VAR1=value
echo $VAR1                        # displays "value"
env | grep '^VAR1='               # displays nothing
VAR2=value env | grep '^VAR2='    # displays "VAR2=value"
echo $VAR2                        # displays nothing

Eu realmente não tinha pensado na diferença entre uma variável de ambiente shell vs. Vou ter que fazer uma pesquisa. Obrigado pela resposta.
Richard Corden
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.