A variável de configuração com valor padrão se comporta de maneira diferente ao preceder um comando?

3

Definir uma variável com um valor padrão de fallback funciona ... contanto que usemos a variável em um comando subseqüente :

$ unset APP_ENV
$ echo $APP_ENV

$ APP_ENV="${APP_ENV:-production}"; echo $APP_ENV
production
$ APP_ENV=staging
$ APP_ENV="${APP_ENV:-production}"; echo $APP_ENV
staging

No entanto, tentando definir a variável imediatamente anterior , o comando que a usa se comporta de maneira diferente:

$ unset APP_ENV
$ echo $APP_ENV

$ APP_ENV="${APP_ENV:-production}" echo $APP_ENV

$ APP_ENV=staging
$ APP_ENV="${APP_ENV:-production}" echo $APP_ENV
staging

Eu não posso envolver minha cabeça porque o segundo exemplo se comporta de maneira diferente?

    
por EvanK 16.07.2015 / 18:11

2 respostas

3

Vamos substituir o ponto-e-vírgula por uma nova linha para tornar a primeira versão mais clara:

APP_ENV="${APP_ENV:-production}"
echo $APP_ENV

A linha 1 é executada completamente antes que o shell olhe para a linha 2.

A linha 1 faz com que $APP_ENV seja igual a production .

A linha 2 acessa essa variável e fornece seu valor ao comando echo .

Agora, a versão de comando único:

APP_ENV="${APP_ENV:-production}" echo $APP_ENV

Primeiro, o shell expande a linha de comando de acordo com a expansão do parâmetro e (não aplicável neste caso) outros tipos de substituição. Como o valor atual de $APP_ENV está vazio, isso se expande para:

APP_ENV="${:-production}" echo

Depois de executar expansões, ele define a variável $APP_ENV to production somente para essa chamada de comando e invoca echo "" com esse valor. Mas echo não se importa que tenha um ambiente varible $APP_ENV em seu ambiente. Só olha para a linha de comando, que consiste em nada. Então isso não ecoa nada.

Veja como você prova que $APP_ENV está sendo definido nesse caso:

$ APP_ENV="${APP_ENV:-production}" env |grep APP_ENV
APP_ENV=production

Em resumo, o segundo exemplo não faz o que você acha que faria, porque a expansão dos parâmetros acontece cedo demais.

    
por 16.07.2015 / 18:50
-4

O segundo formulário está se comportando de maneira diferente porque você está perdendo um ; após a inicialização da variável:

APP_ENV="${APP_ENV:-production}" echo $APP_ENV

deve ser:

APP_ENV="${APP_ENV:-production}"; echo $APP_ENV
                                ^ semicolon that's missing

Corrija isso primeiro e, em seguida, refaça sua pergunta.

    
por 16.07.2015 / 18:18