Una señal es una notificación asíncrona que el kernel (o un proceso) entrega a otro proceso para indicarle que ocurrió algo. No hay canal de datos: es solo un número entero. El proceso receptor interrumpe lo que está haciendo, ejecuta el manejador asociado a esa señal, y continúa —o termina, dependiendo del caso—. Es el mecanismo más primitivo de IPC que existe en Unix, y sigue siendo el más usado para control de procesos en el día a día.
El diseño deliberado es este: la mayoría de señales pueden ser capturadas (caught) o ignoradas por el proceso, lo que le da oportunidad de reaccionar limpiamente. Pero hay dos excepciones absolutas —SIGKILL y SIGSTOP— que el kernel ejecuta directamente sin que el proceso pueda intervenir. Esto existe precisamente para que el administrador siempre tenga un mecanismo de último recurso que no dependa de la cooperación del proceso.
Usas señales cada vez que necesitas cambiar el estado de un proceso sin reiniciar el sistema: para detenerlo ordenadamente, para forzar una recarga de configuración, para pausarlo temporalmente, o para matarlo cuando no responde. Si mandas la señal equivocada, o en el orden equivocado, puedes corromper datos, dejar recursos sin liberar, o simplemente no lograr nada porque el proceso la está ignorando.
Las señales que necesitas conocer en producción son pocas pero precisas:
SIGTERM(15): petición de terminación. El proceso puede capturarla, hacer limpieza —cerrar conexiones, escribir estado, liberar locks— y luego salir. Es la señal correcta por defecto.SIGKILL(9): el kernel destruye el proceso directamente. No hay manejador posible, no hay tiempo de limpieza. Úsala solo cuando SIGTERM no funcionó después de esperar.SIGINT(2): lo que generaCtrl+Cen el terminal. Funcionalmente similar a SIGTERM para la mayoría de procesos interactivos, pero semánticamente distinta.SIGHUP(1): originalmente indicaba que se colgó el terminal (hangup). Los daemons modernos lo han reutilizado por convención para significar “recarga la configuración sin reiniciar”. Nginx, sshd, rsyslog —todos entienden SIGHUP como reload.SIGSTOP: pausa la ejecución del proceso. Como SIGKILL, no puede ser capturada ni ignorada. El proceso queda suspendido en memoria.SIGCONT: reanuda un proceso pausado con SIGSTOP o conCtrl+Z(que envíaSIGTSTP, la versión capturable de SIGSTOP).
La regla profesional es simple: SIGTERM primero, esperas unos segundos, y solo si el proceso no ha salido mandas SIGKILL.
# Ver los procesos de un servicio hipotético que está colgado
# 'ps' nos da el PID; con -C buscamos por nombre de ejecutable
ps -C mi-servicio -o pid,stat,etime,cmd
# SIGTERM primero — el proceso tiene oportunidad de limpiar
kill 4821
# Esperamos hasta 10 segundos comprobando si sigue vivo
# El bucle sale solo cuando el proceso desaparece
for i in $(seq 1 10); do
kill -0 4821 2>/dev/null || { echo "Proceso terminado"; break; }
sleep 1
done
# Si después de 10 segundos sigue ahí, SIGKILL
kill -0 4821 2>/dev/null && kill -9 4821
# ---
# Recargar la configuración de nginx sin cortar conexiones activas
kill -HUP $(cat /run/nginx.pid)
# Equivalente más legible con pkill
pkill -HUP -x nginx
# ---
# Matar todos los procesos llamados exactamente "python3"
# killall busca por nombre de ejecutable (coincidencia exacta por defecto)
killall python3
# Matar por patrón en la línea de comandos completa
# Útil cuando hay varios scripts python3 y solo quieres uno específico
pkill -f 'python3 /opt/mi-app/worker.py'
# ---
# Pausar y reanudar un proceso (útil en debugging o para ceder CPU)
kill -STOP 7743
kill -CONT 7743
# ---
# Ver qué señales tiene capturadas o ignoradas un proceso concreto
# Los campos SigCgt y SigIgn son máscaras de bits en hexadecimal
grep -E 'SigCgt|SigIgn|SigPnd' /proc/7743/status
El bucle con kill -0 merece una explicación: la señal 0 es especial —no se entrega al proceso, solo comprueba si el proceso existe y si tienes permiso para enviarle señales. Retorna 0 si el proceso existe, distinto de 0 si no. Es la forma correcta de sondear si un proceso sigue vivo desde un script.
El kill -HUP $(cat /run/nginx.pid) lee el PID desde el archivo que nginx escribe al arrancar. Esto es más fiable que pkill -x nginx cuando hay varios workers: el archivo .pid siempre apunta al proceso master, que es quien gestiona la recarga. Si usaras pkill -HUP -x nginx sin -x, podrías enviar SIGHUP a todos los workers además del master, con resultados impredecibles según cómo los tenga configurados.
pkill -f busca el patrón contra la línea de comandos completa tal como aparece en /proc/<pid>/cmdline. Esto lo hace mucho más específico que killall, que solo compara el nombre del ejecutable. La trampa de pkill -f es que el patrón es una expresión regular básica, y si es demasiado genérico puede matar procesos que no esperabas —siempre vale la pena verificar primero con pgrep -f 'patrón', que hace exactamente lo mismo pero solo lista en lugar de matar.
La máscara SigCgt en /proc/<pid>/status te dice qué señales tiene el proceso capturadas con un manejador propio. Si el bit correspondiente a SIGTERM (bit 15, valor 0x4000) está activo, el proceso tiene código propio para gestionarla —lo cual es buena señal: probablemente hace limpieza. Si no está capturada, el comportamiento por defecto de SIGTERM es terminar el proceso, lo que en la práctica es lo mismo que quieres pero sin garantía de limpieza explícita.
Un proceso que ignora SIGTERM de forma deliberada —SigIgn con el bit 15 activo— es raro y generalmente un bug o un diseño muy específico. En ese caso, SIGKILL es la única opción, y deberías investigar por qué ese proceso ignoraba la señal antes de asumir que todo está bien después de matarlo.
N° 62