Manejo de errores con Trap

ShellBeginner
Practicar Ahora

Introducción

Cuando se ejecuta un script, a menudo crea archivos temporales o inicia procesos en segundo plano. Si el usuario interrumpe el script, por ejemplo, al presionar Ctrl+C, estos archivos temporales suelen quedar en el sistema y acumularse innecesariamente.

Para evitarlo, los scripts necesitan una forma de detectar cuándo se están deteniendo y ejecutar las acciones de limpieza necesarias.

En Linux, utilizamos el comando trap para capturar señales de interrupción y eventos de salida. Las señales son uno de los mecanismos que utiliza el sistema operativo para comunicarse con los procesos. Por ejemplo, al presionar Ctrl+C normalmente se envía SIGINT, que solicita al proceso que se detenga.

Esto permite definir un procedimiento «al salir» para que el script pueda limpiarse antes de terminar.

En este laboratorio, usted hará lo siguiente:

  1. Crear un script que genere archivos temporales.
  2. Interrumpir el script para comprobar qué archivos quedan.
  3. Implementar un trap para eliminar automáticamente los archivos temporales al salir.

Crear un proceso de larga duración

Primero, cree un script que simule una tarea de larga duración. El script creará un archivo temporal y después permanecerá en espera indefinidamente.

Los scripts de larga duración son habituales en las tareas de administración. Pueden supervisar un registro, esperar una entrada, consultar periódicamente un servicio o procesar trabajos durante un tiempo prolongado. Cuanto más tiempo se ejecuta un script, más importante es limpiar los recursos cuando algo lo interrumpe.

Cree y abra long_process.sh en el directorio del proyecto:

cd ~/project
nano long_process.sh

Escriba este código:

#!/bin/bash

## Create a temporary file
touch temp_data.txt
echo "Temporary file 'temp_data.txt' created."

## Fall asleep (Simulate a long job)
echo "Process is running. Press Ctrl+C to stop..."
while true; do
  sleep 1
done

Guarde el archivo (Ctrl+O, Enter) y salga (Ctrl+X).

Convierta el script en ejecutable:

chmod +x long_process.sh

El problema: si ejecuta este script y después lo detiene con Ctrl+C, el archivo temp_data.txt permanecerá en el disco. Esto se considera una mala práctica, porque las ejecuciones repetidas podrían llenar el espacio del disco con archivos innecesarios.

Los archivos temporales son un ejemplo clásico, pero el mismo problema puede ocurrir con archivos de bloqueo, sockets, puntos de montaje o procesos auxiliares en segundo plano. La limpieza consiste en dejar el sistema en un estado predecible.

Definir una función de limpieza

Para gestionar correctamente la limpieza, se recomienda definir una función específica que contenga toda la lógica necesaria.

Separar la limpieza en una función mantiene el script organizado. También permite reutilizar la misma lógica desde distintas rutas de salida, en lugar de copiarla en varios lugares.

Abra de nuevo el script:

nano long_process.sh

Añada la función cleanup al principio del script:

#!/bin/bash

## Define the cleanup function
cleanup() {
  echo ""
  echo "Cleaning up temporary files..."
  rm -f temp_data.txt
  echo "Cleanup complete."
}

## Create a temporary file
touch temp_data.txt
echo "Temporary file 'temp_data.txt' created."

## Simulate a long-running process
echo "Process is running. Press Ctrl+C to stop..."
while true; do
  sleep 1
done

Guarde el archivo y salga.

En este punto, hemos definido la función, pero todavía no le hemos indicado al script cuándo debe llamarla.

Configurar un trap para capturar señales

Ahora utilizaremos el comando trap para indicarle a Bash: «Si recibe una señal de interrupción, como Ctrl+C, ejecute la función cleanup».

Este es uno de los ejemplos más claros de cómo un script de shell reacciona a eventos del sistema operativo y no solo a entradas de texto. Una señal es un mensaje asíncrono que el sistema o el usuario envía a un proceso, y trap permite que el script responda de forma controlada.

Abra el script:

nano long_process.sh

Añada el comando trap debajo de la definición de la función y antes de que comience la lógica principal.

#!/bin/bash

cleanup() {
  echo ""
  echo "Cleaning up temporary files..."
  rm -f temp_data.txt
  echo "Cleanup complete."
  exit
}

## Register the trap
## SIGINT = Ctrl+C
## EXIT = Any exit (success or failure)
trap cleanup SIGINT EXIT

## The rest of the script...
touch temp_data.txt
echo "Temporary file 'temp_data.txt' created."

echo "Process is running. Press Ctrl+C to stop..."
while true; do
  sleep 1
done

Comprender los argumentos de trap:

  • cleanup: el comando o la función que se ejecutará.
  • SIGINT: la señal que se envía al presionar Ctrl+C.
  • EXIT: una pseudoseñal que se activa cada vez que el script termina, por cualquier motivo.

Usar SIGINT y EXIT hace que la limpieza sea más fiable. SIGINT cubre la interrupción habitual mediante el teclado, mientras que EXIT proporciona una red de seguridad más general para la terminación normal y muchos casos de error.

Guarde el archivo y salga.

Verificar la limpieza

Ahora verifique que el mecanismo funciona correctamente.

Ejecute el script:

./long_process.sh

El script creará temp_data.txt y comenzará a ejecutarse.

A continuación, interrúmpalo presionando Ctrl+C.

Debería ver esta salida:

^C
Cleaning up temporary files...
Cleanup complete.

Por último, compruebe si el archivo ha desaparecido:

ls temp_data.txt

El comando debería devolver un error similar a este:

ls: cannot access 'temp_data.txt': No such file or directory

El comando trap interceptó correctamente la señal de detención y ejecutó el código de limpieza antes de que terminara el script.

Este es un hábito propio de los scripts profesionales: si un script crea un estado temporal, también debe definir cómo eliminarlo. trap es una de las principales herramientas que Bash proporciona para realizar esta tarea.

Resumen

En este laboratorio, aprendió a escribir scripts robustos utilizando Trap.

  1. Señales: comprendió que Ctrl+C envía una señal SIGINT al proceso.
  2. Trap: utilizó trap para capturar señales y ejecutar código específico.
  3. Limpieza: automatizó tareas de mantenimiento para mantener limpio el sistema.

Los scripts profesionales siempre gestionan los distintos escenarios de salida para evitar la corrupción de datos y la permanencia de archivos innecesarios.