Enquanto escrevia algum código, descobri que esta linha:
$ TZ="America/Los_Angeles" date; echo "$TZ"
Thu Dec 24 14:39:15 PST 2015
Fornece corretamente o tempo real em "Los Angeles" e que o valor da variável TZ
não é retido. Tudo como deveria ser esperado.
No entanto, com esta linha, que eu costumava expandir alguns formatos até a data, e que basicamente executa a mesma coisa, mantém o valor de TZ:
TZ="America/Los_Angeles" eval date; echo "$TZ"
Thu Dec 24 14:41:34 PST 2015
America/Los_Angeles
Após vários testes, descobri que isso acontece apenas em algumas conchas. Isso acontece no dash, ksh, mas não no bash ou zsh.
Q's
As perguntas são:
- Por que o valor de TZ está sendo retido no shell atual?
- Como isso poderia ser evitado / controlado (se possível)?
Adicional.
Eu executei testes em várias conchas com estas duas linhas:
myTZ="America/Los_Angeles"
unset TZ; { TZ="$myTZ" date; } >/dev/null; echo -n " direct $TZ"
unset TZ; { TZ="$myTZ" eval date; } >/dev/null; echo " evaled $TZ"
E isso resulta:
/bin/ash : direct evaled America/Los_Angeles
/bin/dash : direct evaled America/Los_Angeles
/bin/sh : direct evaled America/Los_Angeles
/bin/bash : direct evaled
/bin/ksh93 : direct evaled America/Los_Angeles
/bin/lksh : direct evaled America/Los_Angeles
/bin/mksh : direct evaled America/Los_Angeles
/bin/zsh : direct evaled
/bin/zsh4 : direct evaled
O valor TZ afeta o shell em execução em todos os shells, exceto bash e zsh.
Acontece que existe uma razão muito específica para esse comportamento.
A descrição do que acontece é um pouco mais longa.
Somente atribuições.
Uma linha de comando feita (apenas) de atribuições definirá as variáveis para este shell.
O valor dos vars atribuídos será retido.
Comando externo.
As atribuições antes de um comando externo definem variáveis apenas para esse shell:
E eu quero dizer "externo" como qualquer comando que precise ser pesquisado no PATH.
Isso também se aplica a embutidos normais (como cd, por exemplo):
Até aqui tudo é como é normalmente esperado.
Built-Ins especiais.
Mas para embutidos especiais, o POSIX exige que os valores sejam definidos para esse shell .
Estou usando uma chamada para
sh
assumir quesh
é um shell compatível com POSIX.Isso não é algo que geralmente é usado.
Isso significa que as atribuições colocadas na frente de qualquer uma dessas listas de embutidos especiais manterão os valores atribuídos no presente shell em execução:
Isso acontecerá se um shell funcionar conforme a especificação POSIX.
Conclusão:
É possível definir variáveis para apenas um comando, qualquer comando, certificando-se de que o comando não seja um built-in especial. O comando
command
é um builtin regular. Diz apenas ao shell para usar um comando, não uma função. Esta linha funciona em todos os shells (exceto ksh93):Nesse caso, os vars a e b são definidos para o ambiente do comando command e descartados depois disso.
Em vez disso, isso manterá os valores atribuídos (exceto bash e zsh):
Observe que a atribuição após avaliação é única entre aspas para protegê-la de expansões indesejadas.
Portanto: para colocar variáveis no ambiente de comando, use
command eval
:fonte