Buscar..


Sintaxis

  • trap action sigspec ... # Ejecutar "action" en una lista de señales
  • trap sigspec ... # La acción de omisión restablece las trampas para las señales

Parámetros

Parámetro Sentido
-pag Listar las trampas actualmente instaladas
-l Lista de nombres de señales y números correspondientes

Observaciones

La utilidad de trap es un shell especial incorporado. Se define en POSIX , pero bash también agrega algunas extensiones útiles.

Los ejemplos que son compatibles con POSIX comienzan con #!/bin/sh , y los ejemplos que comienzan con #!/bin/bash usan una extensión de bash.

Las señales pueden ser un número de señal, un nombre de señal (sin el prefijo SIG) o la palabra clave especial EXIT .

Los garantizados por POSIX son:

Número Nombre Notas
0 SALIDA Ejecutar siempre en la salida de shell, independientemente del código de salida
1 SIGHUP
2 SIGINT Esto es lo que ^C envía
3 SIGQUIT
6 SIGABRT
9 SIGKILL
14 SIGALRM
15 Sigma Esto es lo que kill envía por defecto

La captura de SIGINT o Ctl + C

La captura se restablece para las subshells, por lo que el sleep seguirá actuando sobre la señal SIGINT enviada por ^C (generalmente al salir), pero el proceso principal (es decir, el script de shell) no lo hará.

#!/bin/sh

# Run a command on signal 2 (SIGINT, which is what ^C sends)
sigint() {
    echo "Killed subshell!"
}
trap sigint INT

# Or use the no-op command for no output
#trap : INT

# This will be killed on the first ^C
echo "Sleeping..."
sleep 500

echo "Sleeping..."
sleep 500

Y una variante que todavía le permite salir del programa principal presionando ^C dos veces en un segundo:

last=0
allow_quit() {
    [ $(date +%s) -lt $(( $last + 1 )) ] && exit
    echo "Press ^C twice in a row to quit"
    last=$(date +%s)
}
trap allow_quit INT

Introducción: limpiar archivos temporales

Puedes usar el comando de trap para "atrapar" las señales; este es el equivalente de shell de la signal() o sigaction() llamada en C y la mayoría de los otros lenguajes de programación para capturar señales.

Uno de los usos más comunes de la trap es limpiar archivos temporales tanto en una salida esperada como inesperada.

Desafortunadamente no hay suficientes scripts de shell hacer esto :-(

#!/bin/sh

# Make a cleanup function
cleanup() {
  rm --force -- "${tmp}"
}

# Trap the special "EXIT" group, which is always run when the shell exits.
trap cleanup EXIT

# Create a temporary file
tmp="$(mktemp -p /tmp tmpfileXXXXXXX)"

echo "Hello, world!" >> "${tmp}"

# No rm -f "$tmp" needed. The advantage of using EXIT is that it still works
# even if there was an error or if you used exit.

Acumula una lista de trabajo de trampa para ejecutar en la salida.

¿Alguna vez ha olvidado agregar una trap para limpiar un archivo temporal o hacer otro trabajo al salir?

¿Alguna vez has puesto una trampa que canceló otra?

Este código hace que sea fácil agregar las cosas que deben hacerse al salir de un elemento a la vez, en lugar de tener una declaración de trap grande en algún lugar de su código, que puede ser fácil de olvidar.

# on_exit and add_on_exit
# Usage:
#   add_on_exit rm -f /tmp/foo
#   add_on_exit echo "I am exiting"
#   tempfile=$(mktemp)
#   add_on_exit rm -f "$tempfile"
# Based on http://www.linuxjournal.com/content/use-bash-trap-statement-cleanup-temporary-files
function on_exit()
{
    for i in "${on_exit_items[@]}"
    do
        eval $i
    done
}
function add_on_exit()
{
    local n=${#on_exit_items[*]}
    on_exit_items[$n]="$*"
    if [[ $n -eq 0 ]]; then
        trap on_exit EXIT
    fi
}

Matando procesos infantiles en la salida

Las expresiones de captura no tienen que ser funciones o programas individuales, también pueden ser expresiones más complejas.

Al combinar los jobs -p y kill , podemos eliminar todos los procesos secundarios generados del shell en exit:

trap 'jobs -p | xargs kill' EXIT

reaccionar al cambiar el tamaño de la ventana de terminales

Hay una señal WINCH (WINdowCHange), que se activa cuando se cambia el tamaño de una ventana de terminal.

declare -x rows cols
 
update_size(){
  rows=$(tput lines) # get actual lines of term
  cols=$(tput cols)  # get actual columns of term
  echo DEBUG terminal window has no $rows lines and is $cols characters wide
}

trap update_size WINCH


Modified text is an extract of the original Stack Overflow Documentation
Licenciado bajo CC BY-SA 3.0
No afiliado a Stack Overflow