Obsługa pułapek i niejawne podpowłoki w skryptach powłoki

12

Załóżmy, że masz skrypt powłoki, który uruchamia pewien rodzaj kodu czyszczenia przez EXITpułapkę, taki jak ten:

#!/bin/bash

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

trap mytrap exit

echo I am at the end of the script.

To, zgodnie z oczekiwaniami, zostanie wydrukowane, It's a trap!gdy skrypt zakończy działanie:

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

Zmodyfikujesz skrypt, aby dodać funkcję, która generuje dane wyjściowe, które ostatecznie są przesyłane do innej komendy, na przykład:

#!/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.

Z powodu potoku wprowadzany kod myfuncjest uruchamiany w podpowłoce ... i wydaje się, że podpowłoki nie dziedziczą trapzachowania rodzica, co oznacza, że ​​jeśli wykonasz tutaj jakieś czynności, które powinny zostać wyczyszczone przez kod pułapki, który wygrał ” tak się stało.

Więc spróbuj tego:

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

I nadal nie uruchamia się mytrappo wyjściu podpowłoki. Okazuje się, że potrzebujesz wyraźnego exit, takiego jak to:

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

Z powyższym kodem mytrapuruchomi się odpowiednio po wyjściu z podpowłoki:

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

Czy to oczekiwane zachowanie? Zaskoczyło mnie kilka rzeczy tutaj:

  • trap ustawienia nie zostały odziedziczone przez podpowłoki
  • niejawne wyjście z podpowłoki nie wydaje się wyzwalać EXIT pułapki
Larsks
źródło

Odpowiedzi:

8

trapWbudowane bash pozwala na słowo kluczowe RETURN. Stąd zmiana:

trap mytrap EXIT

do:

trap mytrap RETURN

Zobacz dyskusję trapw Shell builtins

JRFerguson
źródło