funciones
Funciones
Section titled “Funciones”Bloques de código con nombre que se pueden invocar varias veces. Evitan repetir código y organizan el script.
Creación y llamada
Section titled “Creación y llamada”Sintaxis
Section titled “Sintaxis”#!/bin/bash
function saludar(){ echo "Hola, $1"}
saludar "mundo"Formas equivalentes de declararla:
function saludar { echo "Hola"; } # con la palabra functionsaludar() { echo "Hola"; } # estilo POSIX (más portable)Reglas
Section titled “Reglas”- La función debe estar definida antes de llamarla. Por eso las funciones se colocan al principio del script.
- Se invoca escribiendo su nombre como si fuera un comando, sin paréntesis.
- Una función puede llamar a otras funciones.
- Un nombre de función tiene prioridad sobre un comando externo del mismo nombre.
Estructura recomendada
Section titled “Estructura recomendada”#!/bin/bash
# 1. Funcionesfunction panel_ayuda(){ echo "Uso: $0 <fichero>"}
function procesar(){ echo "Procesando $1"}
# 2. Flujo principalif [[ $# -ne 1 ]]; then panel_ayuda exit 1fi
procesar "$1"Inspeccionar y eliminar
Section titled “Inspeccionar y eliminar”declare -f saludar # muestra el código de la funcióndeclare -F # lista los nombres de todas las funcionesunset -f saludar # elimina la funciónArgumentos y valores de retorno
Section titled “Argumentos y valores de retorno”Argumentos
Section titled “Argumentos”Dentro de una función, $1, $2… son los argumentos de la función, no los del script.
function sumar(){ echo "Recibidos: $#" echo "Todos: $@" echo "Suma: $(( $1 + $2 ))"}
sumar 3 4| Variable | Significado dentro de la función |
|---|---|
$1, $2… |
Argumentos de la función |
$# |
Número de argumentos |
$@ |
Todos los argumentos |
$0 |
Sigue siendo el nombre del script |
Si se necesita usar los argumentos del script dentro de la función, hay que pasarlos: mi_funcion "$@".
Valor de retorno: return
Section titled “Valor de retorno: return”return devuelve únicamente un código de salida (0-255). No sirve para devolver texto ni números grandes.
function es_par(){ (( $1 % 2 == 0 )) # el código de la última orden es el de la función}
if es_par 4; then echo "Es par"fi
es_par 3echo $? # 1function existe(){ [[ -f "$1" ]] || return 1 return 0}Devolver datos: echo y sustitución de comandos
Section titled “Devolver datos: echo y sustitución de comandos”function sumar(){ echo $(( $1 + $2 ))}
total=$(sumar 3 4)echo "$total" # 7Todo lo que la función imprime por salida estándar se captura. Los mensajes de depuración o error deben ir a stderr (>&2) para no mezclarse con el resultado.
function dividir(){ if [[ $2 -eq 0 ]]; then echo "Error: división entre 0" >&2 return 1 fi echo $(( $1 / $2 ))}
resultado=$(dividir 10 2) || echo "Falló"Resumen
Section titled “Resumen”| Necesidad | Mecanismo |
|---|---|
| Indicar éxito o fallo | return 0 / return 1 |
| Devolver un valor | echo + $(...) |
| Modificar una variable del script | Variable global (o declare -n, avanzado) |
Variables locales y ámbito
Section titled “Variables locales y ámbito”Por defecto, las variables de Bash son globales, incluso las creadas dentro de una función.
function f(){ x=10}fecho "$x" # 10 (visible fuera)local limita la variable a la función y a las que esta llame.
function f(){ local x=10 echo "Dentro: $x"}
x=1fecho "Fuera: $x" # 1 (no se modificó)Reglas:
localsolo se puede usar dentro de una función.- Se recomienda declarar
localtodas las variables internas para evitar efectos colaterales. - Para evitar perder el código de salida de un comando, declarar y asignar en líneas separadas:
local resultadoresultado=$(comando_que_puede_fallar) # $? conserva el código del comando# local resultado=$(comando) # $? pasaría a ser el de "local"Recursividad
Section titled “Recursividad”function factorial(){ local n=$1 if (( n <= 1 )); then echo 1 else local anterior anterior=$(factorial $((n - 1))) echo $(( n * anterior )) fi}
factorial 5 # 120>Reutilización con source
Section titled “Reutilización con source”Las funciones de uso común se guardan en un fichero aparte y se cargan con source (o .).
utilidades.sh:
#!/bin/bash
function log(){ echo "[$(date +%T)] $*"}
function error(){ echo "[ERROR] $*" >&2 exit 1}Script que lo usa:
#!/bin/bash
source ./utilidades.sh
log "Iniciando"[[ -f datos.txt ]] || error "Falta datos.txt"Ruta relativa al propio script
Section titled “Ruta relativa al propio script”Para que funcione desde cualquier directorio:
directorio_script="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"source "$directorio_script/utilidades.sh"Comprobar si el fichero existe
Section titled “Comprobar si el fichero existe”[[ -f ./utilidades.sh ]] || { echo "Falta utilidades.sh" >&2; exit 1; }source ./utilidades.shBuenas prácticas
Section titled “Buenas prácticas”- Un fichero de librería solo define funciones y constantes; no ejecuta acciones al cargarse.
- Se le puede dar extensión
.sho.liby no necesita permiso de ejecución. - Evitar nombres de función genéricos que choquen con comandos del sistema (
test,logen algunos entornos): usar un prefijo, por ejemploutil_log.