Estou aprendendo shell scripting através de alguns tutoriais online e cheguei ao seguinte script que declara diferenças de variáveis globais e locais.
#!/bin/bash # Experimenting with variable scope var_change () { local var1="local 1" echo Inside function: var1 is $var1 : var2 is $var2 var1="changed again" var2="changed again" } var1="global 1" var2="global 2" echo Before function call: var1 is $var1 : var2 is $var2 var_change echo After function call: var1 is $var1 : var2 is $var2
E a saída é:
Antes da chamada da função: var1 é global 1 : var2 é global 2
Função interna: var1 é local 1 : var2 é global 2
Após a chamada da função: var1 é global 1 : var2 alterado novamente
Minha pergunta …
Por que var1
está depois a chamada de função " global 1 " em vez de " mudou novamente "? Alguém pode explicar?
Resposta
var1
é declarado local na função. Portanto, durante a execução da função, existem duas variáveis chamadas var1
: a global e a local; mas a função só pode “ver” o local (o local “sombreia” o global). Portanto, dentro da função, tudo o que você fizer em var1
será feito na variável local; o var1
global não é tocado.
Resposta
Uma maneira de pensar nisso é imaginar que local var1="local 1"
tem o efeito de salvar o valor atual de var1
, com a promessa de que no final de a função será restaurada e, em seguida, configurada para "local 1"
. Com este modelo mental, você pode pensar em todas as variáveis como globais e as variáveis sendo restauradas no final das funções.
O exemplo teria sido melhor se, em vez de chamar echo, tanto dentro quanto fora da função chamou outra função que gerou var
.
bash$ show(){ printf " The value of %s in %s is "%s"\n" $1 $2 ${!1} ; } bash$ bar(){ show v1 bar_$1 ; } bash$ foo(){ show v1 before_foo ; local v1 ; show v1 after_local ; \ v1="changed"; show v1 after_change ; bar via_foo ; } bash$ v1="global" bash$ show v1 global_scope The value of v1 in global_scope is "global" bash$ foo The value of v1 in before_foo is "global" The value of v1 in after_local is "" The value of v1 in after_change is "changed" The value of v1 in bar_via_foo is "changed" bash$ bar direct The value of v1 in bar_direct is "global" bash$ show v1 global_scope The value of v1 in global_scope is "global"
Aqui você pode ver na chamada para bar de dentro de foo pega o valor de v1 que foi estabelecido por foo.
Uma pesquisa na web por dynamic scope
vs lexical scope
pode ajudar.
Comentários
- " No final da função, ela será restaurada ", isso deixa minha mente clara! Obrigado
Resposta
No Bash, as variáveis locais devem ser chamadas explicitamente, ou então serão tratadas como globais . Mesmo dentro das funções (que é onde o escopo se aplica).
E, qualquer que seja o escopo definido pela última vez em uma variável – seja local, por meio de uma declaração explícita da palavra local
, ou global por omissão – será o que for retornado no momento em que for chamado por meio de echo
.
Então, em seu exemplo, depois que a função é chamada, o escopo local é definido em var1
, portanto, quaisquer alterações nesta variável não persistem fora da função. Mas o global permanece definido em var2
, então as mudanças nesta variável sim.