Próbowałem następującego skryptu:
#!/bin/bash
trap 'echo "touching a file" && touch $FILE' EXIT
foo1(){
echo "foo1"
}
foo(){
echo "foo"
export FILE=${FILE:-/tmp/file1}
}
(foo1)
foo
Dane wyjściowe powyższego skryptu były następujące:
[root@usr1 my_tests]# ./test.sh
foo1
foo
touching a file
Jednak spodziewałem się, że pułapka zostanie również wywołana przy wyjściu z foo1
, która jest wywoływana w podpowłoce.
- Czy jest to oczekiwane?
- Czy
trap
dziedziczy się podpowłoka? - Jeśli tak, to w jakim przypadku
trap
dziedziczy podpowłoka?
Odpowiedzi:
Procedury obsługi pułapek nigdy nie są dziedziczone przez podpowłoki. Jest to określone przez POSIX :
Zauważ, że ignorowane sygnały (
trap '' SIGFOO
) pozostają ignorowane w podpowłoce (oraz w programach zewnętrznych uruchamianych również przez powłokę).źródło
set -E
, aby podpowłoki dziedziczyły pułapki, ale NAPRAWDĘ trudno jest to naprawić (przynajmniej z mojego doświadczenia).trap
nie jest proponowany do podpowłoki, ale niektóre sposoby umożliwiają podpowłoce zgłaszanie pułapek powłoki nadrzędnej, a inne nie. Zrobiłem kilka testów na macos z bash.GNU bash, wersja 4.4.12 (1) -release (x86_64-apple-darwin16.3.0):
GNU bash, wersja 3.2.57 (1) -release (x86_64-apple-darwin16):
Warto wiedzieć, że
trap_output="$(trap)"
zadziała, aby przechwycić wyjście pułapki. Nie mogę wymyślić żadnego innego sposobu, aby to zrobić, gdyby to nie zadziałało poza zrobieniemtrap >trap_output_file
go do pliku (fifo nie zadziałabash 3.2.57
), a następnie ponownym odczytaniem go za pomocątrap_output="$(<trap_output_file)"
fifo nie zadziała,
bash 3.2.57
ponieważtrap &
jest pusty,bash 3.2.57
ale niebash 4.4.12
GNU bash, wersja 4.4.12 (1) -release (x86_64-apple-darwin16.3.0):
GNU bash, wersja 3.2.57 (1) -release (x86_64-apple-darwin16):
źródło
trap
definicje nie są propagowane do podpowłok.Weryfikuj przez:
trap "echo bla" 1 2 3"
(trap)
źródło
(trap)
jako specjalny przypadek, dzięki czemu podpowłoka może zgłaszać (ale nie używać) pułapek powłoki nadrzędnej. Dlatego ten test nie zawsze jest wiarygodny.ksh88
,bosh
(Schily Bourne shell) iheirloom-sh
. Masz rację:ksh93
zachowuje się inaczej.bash
nic nie wyświetla, jeśli zadzwonisz(trap)
.