2011-01-07 24 views
9

Hasta donde yo sé, hay dos formas de crear variables locales en una función bash: crear una subcadena o declarar cada variable como local.Variables locales en bash: local vs subshell

Por ejemplo:

# using local 
function foo 
{ 
    local count 
    for count in $(seq 10) 
    do 
    echo $count 
    done 
} 

o

# using subshell 
function foo 
{ 
    (
    for count in $(seq 10) 
    do 
     echo $count 
    done 
) 
} 

obvisously la versión con el subnivel es más fácil de escribir, ya que no tiene que preocuparse acerca de declarar todas las variables locales (por no hablar de (entorno) variables creadas/exportadas por herramientas como getopts). Pero podría imaginar que crear una subshell tiene un costo.

¿Cuál es el mejor enfoque? ¿Cuáles son los pros/contras?

+0

, así ejecutar el comando 'tiempo' más de 1000 pruebas y encontrar fuera de los gastos generales, creo que es pequeño o inexistente. – Anders

Respuesta

9

La creación de un subconjunto implica un fork(), por lo que definitivamente tiene una sobrecarga en comparación con una variable local. Mientras que las subcapas son baratas — no se preocupe por su costo cuando necesite una — que no sean gratuitas.

Si su script va a ser muy utilizado y el rendimiento realmente importa (por lo que tendrá cientos de usuarios todos ejecutando al mismo tiempo, muchas veces al día), entonces puede que le preocupe el costo de rendimiento de la sub-shell. OTOH, si lo ejecutas una vez al mes y el script en su conjunto dura menos de 10 segundos, probablemente no lo harás.

Sin embargo, en términos de claridad, es mucho mejor ser explícito y declarar las variables —, reduce el riesgo de que se rompa la secuencia de comandos porque alguien viene y dice "claramente no se necesita esta subcapa" (y realmente no lo es, me gustaría eliminar las subcapas de tus funciones).

Observe la evolución de las secuencias de comandos de Perl. Comenzaron como un todo-gratis con variables que surgieron a pedido. Gradualmente se han vuelto más rigurosos, con un estilo normal ahora predeclare todas las variables. Hasta cierto punto, las shells han seguido un camino similar — pero no tan rigurosamente como Perl. Awk es también un estudio de caso interesante; sus funciones utilizan variables globales a menos que sean argumentos para la función, lo que lleva a que las funciones se escriban con 3 argumentos activos (por ejemplo) y 5 argumentos inactivos que definan efectivamente las variables locales. Es ligeramente excéntrico, aunque 'funciona'.

0

Ahora, asegurarse de que todas las funciones siempre declaran todas las variables como locales, es bastante difícil.

creo que esto es muy propenso a errores y prefieren utilizar siempre subshell-funciones:

f() (
echo "we are a subshell" 
) 

No hay necesidad de declarar variables locales - pero también hay manera de cambiar las variables globales. ¡Lo cual es BUENO en mi opinión!

Una consecuencia adicional es que siempre debe verificar el código de retorno/salida de dichas funciones y actuar en consecuencia. Esto es porque no puede salir de su script desde una función de subshell!

f() (
    echo "Trying to exit" 
    exit 1 
) 

f 
echo "Did not exit" 

Esto NO saldrá de su secuencia de comandos. Es necesario hacerlo de esta manera: "Pero me podía imaginar que la creación de un subnivel tiene una sobrecarga"

f() (
    echo "Trying to exit" 
    exit 1 
) 

f || exit $? 
echo "Did not exit" 

Esto salir