Introducción
Al escribir scripts, debe controlar cómo se accede a los datos y cómo las funciones comunican si se ejecutaron correctamente o si fallaron.
Si usa el mismo nombre de variable en dos lugares distintos, una variable podría sobrescribir accidentalmente a la otra. Este es un error frecuente de programación. Lo solucionamos mediante el ámbito (scope), que mantiene las variables locales dentro de una función.
Además, las funciones necesitan una forma de informar al script principal si se ejecutaron correctamente o si fallaron. En Bash, esto se hace mediante códigos de estado de retorno.
Este tema reúne dos ideas fundamentales para los scripts grandes: evitar que las variables afecten a lugares donde no deberían hacerlo y usar los estados de éxito o error para controlar el flujo de ejecución.
En este laboratorio aprenderá lo siguiente:
- Ámbito de las variables: usar
localpara evitar conflictos entre variables. - Estado de retorno: usar códigos de salida (0 para indicar éxito y un valor distinto de cero para indicar un error) para controlar el flujo del script.
Ámbito de las variables: global y local
De forma predeterminada, las variables de Bash son globales. Esto significa que, si define una variable dentro de una función, puede acceder a ella y modificarla desde cualquier lugar del script. Esto puede provocar errores difíciles de controlar: una parte del script podría cambiar accidentalmente datos que otra parte necesita.
Para evitarlo, usamos la palabra clave local. Una variable local existe únicamente dentro de la función en la que se crea.
Este es uno de los aspectos que debe tener en cuenta al escribir scripts de shell. Bash permite comenzar rápidamente, pero esa facilidad también puede hacer que los datos se filtren inesperadamente por todo el script. El ámbito establece dónde puede verse una variable.
Veamos la diferencia.
Cree un script llamado scope.sh:
cd ~/project
nano scope.sh
Añada el siguiente código:
#!/bin/bash
## This is a Global variable
city="New York"
print_city() {
## This is a Local variable. It shares the name 'city', but it is a separate variable.
local city="London"
echo "Inside function: $city"
}
echo "Before function call: $city"
## Run the function
print_city
## Check if the Global variable was changed
echo "After function call: $city"
Guarde el archivo (Ctrl+O, Enter) y salga (Ctrl+X).
Convierta el script en ejecutable y ejecútelo:
chmod +x scope.sh
./scope.sh
Resultado:
Before function call: New York
Inside function: London
After function call: New York
Observe que la variable city situada fuera de la función conserva el valor "New York". La función usó su propia copia local de city ("London") y no modificó la variable global.
Si no hubiéramos usado local, la función habría sobrescrito la variable global y la última línea habría mostrado "London".
Por eso local se vuelve más importante a medida que crecen los scripts. En una demostración breve, las variables globales pueden parecer inofensivas. Sin embargo, en un script de mantenimiento más largo, reutilizar un nombre de variable puede provocar errores sutiles y difíciles de diagnosticar.
Códigos de estado de retorno
En muchos lenguajes de programación, las funciones devuelven datos, como una cadena o un número. En Bash, return se usa exclusivamente para devolver códigos de estado que indican éxito o error.
- 0: éxito.
- 1-255: error.
No confunda return con echo.
echomuestra texto en pantalla, o lo guarda en una variable si se captura su salida.returnenvía silenciosamente un número al sistema para indicar «se ejecutó correctamente» o «falló».
Esta diferencia es fundamental en la programación con shell. La salida de texto y la comunicación del estado son dos canales independientes. Una función puede mostrar información legible para las personas mediante echo, pero el valor de return está pensado para controlar el flujo, no para transportar datos generales.
Creemos una función que simule un error devolviendo el código 5.
Cree status.sh:
nano ~/project/status.sh
Añada el siguiente código:
#!/bin/bash
check_file() {
echo "Checking for file..."
## We simulate a specific error by returning Code 5
return 5
}
check_file
Guarde el archivo y salga.
Conviértalo en ejecutable y ejecútelo:
chmod +x status.sh
./status.sh
Salida:
Checking for file...
Puede ver el texto, pero ¿dónde está el número 5? La función lo devolvió silenciosamente. En el siguiente paso aprenderá a capturarlo y usarlo.
Capturar el código de retorno ($?)
Para consultar el código de retorno del último comando o función ejecutado, Bash proporciona una variable especial: $?.
Cuando check_file termina de ejecutarse, $? contiene automáticamente el valor 5.
Regla fundamental: debe leer $? inmediatamente después de ejecutar el comando. En cuanto ejecute otro comando, incluso un echo sencillo, $? se actualiza con el estado de ese nuevo comando.
Modifique status.sh para capturar el código.
Abra el archivo:
nano status.sh
Actualice el script con este contenido:
#!/bin/bash
check_file() {
echo "Checking for file..."
return 5
}
check_file
## Capture the return code immediately into a variable
ret_val=$?
echo "The function returned: $ret_val"
Guarde el archivo y salga. Vuelva a ejecutarlo:
./status.sh
Salida:
Checking for file...
The function returned: 5
Ahora ha capturado el código de error en la variable ret_val.
Capturar el código de retorno permite que el resto del script reaccione de forma adecuada. Una instrucción if posterior puede comprobar ese valor y decidir si debe continuar, volver a intentarlo o detenerse. Así, las funciones pueden colaborar en scripts grandes en lugar de actuar como fragmentos de código aislados.
Actuar según el estado de retorno
Ahora que tenemos el código de estado, podemos usar una instrucción if para gestionar los errores correctamente.
- Si el código es
0, todo funciona bien. - Si el código es
5, sabemos exactamente qué ocurrió, por ejemplo, que falta el archivo.
Así se comportan los comandos estándar de Linux. Por ejemplo, grep devuelve 0 si encuentra una coincidencia y 1 si no la encuentra.
Actualice status.sh para añadir esta lógica:
nano status.sh
Añada la lógica condicional:
#!/bin/bash
check_file() {
echo "Checking for file..."
return 5
}
check_file
ret_val=$?
## Logic based on the return code
if [ $ret_val -eq 0 ]; then
echo "Success: File found."
elif [ $ret_val -eq 5 ]; then
echo "Error: File missing (Code 5)."
else
echo "Unknown Error: Code $ret_val"
fi
Guarde el archivo y salga. Ejecútelo:
./status.sh
Salida:
Checking for file...
Error: File missing (Code 5).
Ahora ha implementado una gestión básica de errores. Si la comprobación del archivo falla, el script lo detecta y puede mostrar un mensaje de error específico en lugar de bloquearse o continuar sin comprobar el resultado.
Resumen
En este laboratorio ha practicado dos conceptos fundamentales de scripting:
- Ámbito de las variables (
local): usarlocalgarantiza que las variables dentro de las funciones no sobrescriban las variables globales, lo que mantiene el comportamiento del script predecible. - Estado de retorno (
return,$?): usar códigos de salida permite que las funciones comuniquen su éxito o error al script principal y ayuda a escribir scripts capaces de gestionar los errores de forma inteligente.
Use siempre local para las variables dentro de las funciones, a menos que necesite modificar específicamente una variable global.



