bash variável visibilidade em subshell de substituição de comando

6

Estou lendo um livro de scripts de shell do Linux e encontrei o seguinte aviso:

"Command substitution creates what's called a subshell to run the enclosed command. A subshell is separate child shell generated from the shell that's running the script. Because of that, any variables you create in the script aren't available to the subshell command".

Eu tentei criar uma variável na CLI do meu bash shell atual e depois inserir o subshell para verificar se eu posso imprimi-lo na tela. Então sim, eu não posso fazer isso, parece estar de acordo com a citação acima. No entanto, executei o seguinte script com a substituição de comando:

#!/bin/bash
var=5.5555
ans=$(echo $var)
echo $ans

E o resultado é:

5.5555

Como eu entendi, ele não deveria imprimir o valor de var, já que a subshell não deveria ser capaz de "ver". Por que isso acontece?

    
por Donatas 12.09.2016 / 09:49

2 respostas

7

A declaração:

Because of that, any variables you create in the script aren't available to the subshell command.

é falso. O escopo de uma variável definida no shell pai é o script inteiro (incluindo subshells criados com a substituição de comandos).

Em exibição:

#!/bin/bash
var=5.5555
ans1=$(echo $var)
ans2=$(var=6; echo $var)
echo $ans1
echo $ans2

dará o resultado:

5.5555
6

$var é resolvido pelo subnível:

  • se nenhuma variável local for especificada, o valor de três variáveis globais será usado
  • se uma variável local for especificada, ela usa seu valor

Veja também o exemplo 21-2 .

    
por 12.09.2016 / 09:58
8

A declaração citada não é verdadeira. Também não é verdade que a variável tenha sido pré-substituída antes que o subshell seja executado.

Você pode validar isso diretamente usando indireto de variável :

$ x=hello
$ echo Result is $(y=x ; echo ${!y} ; echo world)
Result is hello world

A variável x está definitivamente disponível diretamente para o subshell (em vez de ter seu valor expandido anteriormente) porque ${!y} lê a variável cujo nome é armazenado em y - que não existia na época em que o subshell foi criado.

Uma leitura caridosa da passagem do livro seria que significa dizer que a "variável" não está disponível porque você não pode modificar seu valor persistentemente. Quaisquer atribuições de variáveis feitas em um subshell não estarão disponíveis no shell pai posteriormente, seja criando novas variáveis (como y ) ou atribuindo valores de substituição a variáveis existentes. Se o subshell atribuído a x , o novo valor teria efeito dentro do subshell, mas a leitura dele depois daria o valor original:

$ x=world
$ echo $(x=hello ; echo $x)
hello
$ echo $x
world

Não é uma maneira muito clara de expressar isso, pelo menos na passagem que você citou. Se o livro inteiro é assim, você pode encontrar um melhor (ou ler perguntas aqui).

    
por 12.09.2016 / 10:49

Tags