Considere as duas funções a seguir:
f1() {
if [ "$a" == "" ]; then
a="0";
else
a=$(($a+1));
fi;
echo "$a";
}
f2() {
echo "f1(): $($1)";
}
Se eu ligar f1
várias vezes a
será incrementado conforme o esperado:
$ f1
0
$ f1
1
$ f1
2
Mas se eu chamar f1
de f2
a
restos 0
:
$ f2 "f1"
f1(): 0
$ f2 "f1"
f1(): 0
Já ouvi (e também experimentei) que variáveis declaradas em funções são globais. Então por que existe essa diferença? É um caso especial ou não ligo f1
de f2
forma correta?
Ok, acabei de notar que mudar f2
a definição para:
f2() {
eval "$1";
}
resolve o problema, mas ainda seria interessante saber qual é o propósito do primeiro tipo de chamada $($1)
. O que ele faz exatamente?
Também notei que não consigo atribuir o valor de "retorno" f1
a uma variável em f2
.
f2() {
...
res=$(eval "$1");
...
}
res
será o mesmo após cada chamadaf2 "f1"
Por quê?
Em f1 o valor de
a
é global (no bash), seria local sea
for definido com:Altere a definição de f1 para:
para tornar a variável local.
Para f2: f2 é chamado em um subshell $(f2). Variáveis de subshells não afetam o pai.
Quero agradecer a todos os comentários que mencionam o subshell. No entanto, quero dar uma resposta mais detalhada.
Cada vez que
f1
for chamado def2
um novo subshell será criado e apenas as 3 instruções serão executadas.a
torna-se global e inicializado no subshell (pelo menos no meu sistema, porquef1
as chamadas repetitivas incrementama
). Masa
não existe no próximo subshell criado.