Estoy aprendiendo a usar scripts de shell a través de algunos tutoriales en línea y llegué al siguiente script que declara diferencias de variables globales y locales.
#!/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
Y el resultado es:
Antes de la llamada a la función: var1 es global 1 : var2 es global 2
Función interna: var1 es local 1 : var2 es global 2
Después de la llamada de función: var1 es global 1 : var2 es cambiado de nuevo
Mi pregunta …
¿Por qué var1
después la llamada de función " global 1 " en lugar de " cambió nuevamente "? ¿Alguien puede explicarlo?
Answer
var1
se declara local en la función. Entonces, durante la ejecución de la función hay dos variables llamadas var1
: la global y la local; pero la función sólo puede «ver» la local (la local «sombrea» la global). Entonces, dentro de la función, cualquier cosa que haga en var1
se hará en la variable local; el var1
global no se toca en absoluto.
Respuesta
Una forma de pensar en ello es imaginar que local var1="local 1"
tiene el efecto de guardar el valor actual de var1
, con la promesa de que al final de la función será restaurada, y luego configurándola en "local 1"
. Con este modelo mental, puede pensar en todas las variables como globales, y las variables se restauran al final de las funciones.
El ejemplo hubiera sido mejor si en lugar de llamar a echo tanto dentro como fuera de la función hubiera llamó a otra función que había generado 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"
Aquí puede ver en la llamada a la barra desde adentro foo toma el valor de v1 que fue establecido por foo.
Una búsqueda web de dynamic scope
frente a lexical scope
podría ayudar.
Comentarios
- " Al final de la función se restaurará ", ¡esto aclara mi mente! Gracias
Responder
En Bash, las variables locales deben ser llamadas explícitamente, o de lo contrario serán tratadas como globales . Incluso dentro de las funciones (que es donde se aplica el alcance).
Y, sea cual sea el alcance que se configuró por última vez en una variable, ya sea local, mediante una declaración explícita de la palabra local
, o global por omisión: será lo que se devuelva en el momento en que se llame a través de echo
.
Entonces, en En su ejemplo, después de llamar a la función, el alcance local se establece en var1
, por lo que cualquier cambio en esta variable no persiste fuera de la función. Pero global permanece configurado en var2
, por lo que los cambios en esta variable sí.