Dominá las funciones en Bash: De lo básico a la gestión de variables y retornos
Si alguna vez tuviste que escribir un script de Bash que pasó de ser una simple lista de comandos a un monstruo de cientos de líneas, seguro te encontraste con el mismo problema: el código es un caos, repetís la misma lógica una y otra vez, y mantenerlo es una pesadilla. Ahí es donde entran las funciones.
En este tutorial, vamos a dejar de lado los scripts de "un solo uso" para empezar a construir herramientas robustas. Vas a aprender cómo definir funciones, cómo pasarles datos, cómo manejar el alcance de las variables para no romper nada y, muy importante, cómo entender qué significa realmente un return en Bash (porque no es lo mismo que en Python o JavaScript).
Este post está pensado para desarrolladores, sysadmins o cualquier persona que ya use la terminal pero quiera profesionalizar sus automatizaciones.
¿Por qué usar funciones en tus scripts?
Antes de tirar código, entendamos el porqué. Las funciones te permiten:
- Modularizar: Dividís un problema grande en tareas pequeñas y manejables.
- Reutilizar: Escribís la lógica una vez y la llamás donde la necesites.
- Legibilidad: Un script que dice
backup_databasees mucho más fácil de leer que un bloque de 20 comandostar,scpyrmsueltos. - Facilidad de testing: Podés probar una parte de tu lógica sin ejecutar todo el proceso.
1. Definición básica de una función
En Bash, tenés un par de formas de definir una función. Las dos más comunes son:
# Estilo estándar (recomendado por su compatibilidad)
mi_funcion() {
echo "Hola desde la función"
}
# Estilo con la palabra clave 'function' (más estilo C/JS)
function mi_otra_funcion {
echo "Hola desde la otra función"
}
Para ejecutarla, simplemente escribís su nombre como si fuera un comando.
Ejemplo práctico: Salida esperada
Crea un archivo llamado test_basico.sh:
#!/bin/bash
saludar() {
echo "¡Hola, colega!"
}
echo "Iniciando el script..."
saludar
echo "Script finalizado."
Salida esperada:
Iniciando el script...
¡Hola, colega!
Script finalizado.
2. Pasando argumentos a las funciones
Acá es donde muchos se traban. En Bash, no pasamos argumentos entre paréntesis como en otros lenguajes. No hacés mi_funcion(arg1, arg2).
En su lugar, los argumentos se pasan como si estuvieras ejecutando el comando, y dentro de la función los accedés mediante las variables posicionales: $1, $2, $3, y así sucesivamente. $@ representa a todos los argumentos y $# la cantidad de ellos.
Ejemplo con múltiples argumentos
Vamos a crear una función que reciba un nombre y una edad.
#!/bin/bash
presentar_usuario() {
local nombre=$1
local edad=$2
echo "El usuario $nombre tiene $edad años."
}
# Llamada a la función
presentar_usuario "Juan" 30
presentar_usuario "Marta" 25
Salida esperada:
El usuario Juan tiene 30 años.
El usuario Marta tiene 25 años.
Tip Pro: Siempre usá comillas dobles al asignar los argumentos a variables (
local nombre="$1") para evitar problemas si el argumento contiene espacios.
3. El concepto de Ámbito (Scope) y Variables Locales
Este es el punto donde la mayoría de los scripts de Bash fallan y se vuelven imposibles de debuguear. Por defecto, todas las variables en Bash son globales.
Si definís una variable dentro de una función sin especificar que es local, esa variable va a existir en todo tu script, pudiendo sobrescribir valores que tenías afuera.
El peligro de las variables globales
Mirá este error común:
#!/bin/bash
valor=10
cambiar_valor() {
valor=20 # ¡Esto modifica la variable global!
}
cambiar_valor
echo "El valor ahora es: $valor"
Salida: El valor ahora es: 20. Lo que querías era mantener el 10.
La solución: El comando local
Para evitar esto, siempre que declares una variable dentro de una función que solo deba existir ahí, usá la palabra clave local.
#!/bin/bash
valor=10
cambiar_valor_seguro() {
local valor=20 # Esta variable solo vive acá adentro
echo "Dentro de la función: $valor"
}
cambiar_valor_seguro
echo "Fuera de la función: $valor"
Salida esperada:
Dentro de la función: 20
Fuera de la función: 10
Regla de oro: Si estás dentro de una función, todo lo que declares debería llevar local a menos que tu intención explícita sea modificar el estado global del script.
4. Retornar valores: El gran malentendido
Acá es donde la mayoría de los programadores que vienen de Python, Ruby o JS meten la pata. En Bash, el comando return no devuelve un valor de datos (como un string o un objeto), sino un código de estado (exit status).
El código de estado es un número entero entre 0 y 255:
0: Significa éxito (success).1-255: Significa error o algún estado específico.
Si querés que una función te "devuelva" un texto o un número para usarlo en una variable, tenés dos caminos principales: usar echo y captura de salida, o usar variables globales (aunque esto último es menos limpio).
Opción A: Usar return para estados (Correcto)
#!/bin/bash
verificar_archivo() {
if [[ -f "$1" ]]; then
return 0 # Éxito
else
return 1 # Error
fi
}
archivo="/etc/passwd"
if verificar_archivo "$archivo";
then
echo "El archivo existe."
else
echo "El archivo no existe."
fi
Opción B: Usar echo para devolver datos (El estándar de oro)
Si necesitás que la función te devuelva un resultado procesado, hacé un echo del resultado y capturalo con la sintaxis $(...).
#!/bin
sumar() {
local n1=$1
local n2=$2
local resultado=$((n1 + n2))
echo "$resultado" # "Retornamos" el valor por salida estándar
}
# Capturamos la salida de la función en una variable
suma_total=$(sumar 15 25)
echo "La suma es: $suma_total"
Salida esperada:
La suma es: 40
Buenas prácticas y errores comunes
Para que tus scripts no sean un dolor de cabeza, seguí estas recomendaciones:
✅ Qué hacer
- Usar
localsiempre: No dejes que las variables se escapen de la función. - Nombres descriptivos: En vez de
func1(), usálimpiar_logs()oenviar_notificacion(). - Validar argumentos: Antes de usar
$1, chequeá si existe con[[ -z "$1" ]]. - Comentar la función: Un comentario breve sobre qué recibe y qué devuelve ayuda muchísimo.
❌ Qué evitar
- No confundir
returnconecho: Recordá quereturnes para decir "todo salió bien" o "algo falló". - No usar variables globales para cálculos: Si la función calcula algo, que lo devuelva por
echo. - No hacer funciones gigantes: Si tu función tiene más de 50 líneas, probablemente necesite ser dividida en dos.
Conclusión
Dominar las funciones en Bash es el primer paso para pasar de ser alguien que "tira comandos" a alguien que "construye herramientas". Entendiste que las funciones permiten modularizar el código, que los argumentos se manejan por posición, que local es tu mejor amigo para evitar efectos secundarios y que el return es para estados, no para datos.
Próximos pasos:
Ahora que sabés esto, intentá refactorizar uno de tus scripts viejos. Agrupá las tareas repetitivas en funciones y empezá a usar local. Vas a notar la diferencia en la claridad de tu código inmediatamente.
¡Mucha suerte con tus automatizaciones!
DUGLAS MORENO
Comentarios (0)
Sé el primero en comentar.