O manual do bash diz "O ambiente para qualquer comando ou função simples pode ser aumentado temporariamente prefixando-o com atribuições de parâmetros". Eu também entendo que variáveis exportadas são passadas por padrão para subprocessos que o bash cria. Estou testando alguns comportamentos com variáveis não exportadas, e o que eu não entendo é como isso funciona quando as atribuições são seguidas pelo operador ';', e então alguns outros comandos são executados.
Meu caso é o seguinte:
VAR=hello; echo $VAR
imprime "olá".
VAR=hello :; echo $VAR
imprime uma nova linha.
VAR=hello; echo $VAR; bash -c 'echo $VAR'
imprime "olá" e uma nova linha.
A questão é, no primeiro e terceiro comando, por que VAR está sendo expandido? Eles são comandos diferentes, com (aparentemente) nenhuma atribuição de parâmetro prefixada.
PS: Tentei no bash 4.4.20 e 5.1.16 e o comportamento foi o mesmo em ambos.
Parece que você está basicamente perguntando sobre exportação e quando algo precisa ser exportado. Vamos dar uma olhada em cada um dos seus exemplos:
VAR=hello; echo $VAR
: estes são dois comandos, executados na mesma sessão de shell . Como estamos na mesma sessão, a primeira atribuição de variável é suficiente e não há necessidade deexport
nada.VAR=hello :; echo $VAR
: aqui também temos dois comandos na mesma sessão de shell , mas neste caso, a variável foi explicitamente definida apenas para a duração do:
comando. Então aqui, você não definiu a variável na sua sessão de shell, você apenas a definiu para aquele comando. Então, quando você retorna ao shell, a variável não está definida, portanto, o echo imprime uma linha vazia.VAR=hello; echo $VAR; bash -c 'echo $VAR'
: aqui temos uma sessão de shell na qual você executaVAR=hello
eecho $VAR
. Você então inicia uma nova sessão de shell, que portanto não herdará variáveis não exportadas , e naquela segunda sessão, oecho $VAR
não imprime nada. É aqui que exportar teria feito a diferença:Embora, como foi apontado nos comentários,
:
seja um "built-in especial" e, portanto, de acordo com o POSIX, a atribuição emVAR=hello :
deve ser visível no ambiente do shell. O Bash não faz isso no modo normal, mas faz no modo POSIX , assim como praticamente qualquer outro shell POSIX.O mesmo
unset VAR; VAR=hello :; echo "$VAR"
acontece com printhello
no modo POSIX bash (bash -o posix
), dash ou ksh. Isso seria diferente com egtrue
em vez de:
, já que é apenas um comando regular (integrado ou não).