Я попробовал следующий скрипт:
#!/bin/bash
trap 'echo "touching a file" && touch $FILE' EXIT
foo1(){
echo "foo1"
}
foo(){
echo "foo"
export FILE=${FILE:-/tmp/file1}
}
(foo1)
foo
Выход для вышеуказанного скрипта был:
[root@usr1 my_tests]# ./test.sh
foo1
foo
touching a file
Однако я ожидал, что trap-сообщение также будет вызвано при выходе из foo1
, что называется в подоболочке.
- Это ожидается?
- Является ли
trap
наследоваться субоболочкой? - Если да, то в каком случае
trap
наследуется подоболочка?
Ответы:
Обработчики ловушек никогда не наследуются подоболочками. Это указано в POSIX :
Обратите внимание, что игнорируемые сигналы (
trap '' SIGFOO
) остаются игнорируемыми в подоболочке (и во внешних программах, запускаемых оболочкой, тоже).источник
set -E
для того, чтобы подоболочки наследовали ловушки, но ДЕЙСТВИТЕЛЬНО сложно получить права (по крайней мере, по моему опыту).trap
не распространяется на подоболочки, но некоторые способы позволяют подоболочке сообщать о ловушках родительской оболочки, а другие - нет. Я сделал несколько тестов на MacOS с Bash.GNU bash, версия 4.4.12 (1) -релиз (x86_64-apple-darwin16.3.0):
GNU bash, версия 3.2.57 (1) -релиз (x86_64-apple-darwin16):
Это хорошо знать, что
trap_output="$(trap)"
это сработает для захвата вывода ловушек. Я не могу придумать другого способа сделать это, если это не сработало, кромеtrap >trap_output_file
как вывести его в файл (fifo не будет работатьbash 3.2.57
), а затем прочитать его обратно с помощьюtrap_output="$(<trap_output_file)"
fifo не будет работать,
bash 3.2.57
потому чтоtrap &
пуст для,bash 3.2.57
но неbash 4.4.12
GNU bash, версия 4.4.12 (1) -релиз (x86_64-apple-darwin16.3.0):
GNU bash, версия 3.2.57 (1) -релиз (x86_64-apple-darwin16):
источник
trap
определения не распространяются на подоболочки.Проверить по:
trap "echo bla" 1 2 3"
(trap)
источник
(trap)
как особый случай, так что подоболочка может сообщать (но не использовать) ловушки родительской оболочки. Так что этот тест не всегда надежен.ksh88
,bosh
(Шили Bourne Shell) иheirloom-sh
. Вы правы:ksh93
ведет себя по-разному.bash
ничего не выводит, если вы звоните(trap)
.