Manejo de trampas y subcapas implícitas en scripts de shell

12

Digamos que tiene un script de shell que ejecuta algún tipo de código de limpieza a través de una EXITtrampa, como este:

#!/bin/bash

mytrap () {
  echo "It's a trap!" >&2
}

trap mytrap exit

echo I am at the end of the script.

Esto, como se esperaba, se imprimirá It's a trap!cuando salga el script:

$ sh myscript
I am at the end of the script.
It's a trap!

Modifica el script para agregar una función que genera un resultado que finalmente se canaliza a otro comando, como este:

#!/bin/bash

mytrap () {
  echo "It's a trap!" >&2
}

myfunc () {
  echo "I've got a bad feeling about this..."
}

trap mytrap exit

myfunc | cat > /dev/null

echo I am at the end of the script.

Debido a la tubería, el código myfuncse ejecuta en una subshell ... y las subshells no parecen heredar el trapcomportamiento del padre, lo que significa que si realiza alguna acción aquí que debería ser limpiada por su código de trampa que ganó ' No suceda

Entonces intentas esto:

myfunc () {
  trap mytrap EXIT
  echo "I've got a bad feeling about this..."
}

Y todavía no se dispara mytrapcuando la subshell sale. Resulta que necesitas un explícito exit, como este:

myfunc () {
  trap mytrap EXIT
  echo "I've got a bad feeling about this..."
  exit
}

Con el código anterior, mytrapse activará adecuadamente al salir de la subshell:

$ sh myscript 
It's a trap!
I am at the end of the script.
It's a trap!

¿Es ese comportamiento esperado? Me sorprendieron varias cosas aquí:

  • trap los subconjuntos no heredaron la configuración
  • la salida implícita de una subshell no parece desencadenar una EXIT trampa
larsks
fuente

Respuestas:

8

El bash trapincorporado permite la palabra clave RETURN. De ahí el cambio:

trap mytrap EXIT

a:

trap mytrap RETURN

Ver la discusión de trapin -shell-builtins

JRFerguson
fuente