Стандартный подоболочка против подзаголовка подстановки команд

8

Пожалуйста, объясните эти выводы:

$ line(){ echo -------------; echo $BASHPID; }
$ trap 'echo bye' EXIT; trap -p; line; (trap -p; line); echo "$(trap -p; line)"

trap -- 'echo bye' EXIT
trap -- '' SIGTSTP
trap -- '' SIGTTIN
trap -- '' SIGTTOU
-------------
6176
trap -- '' SIGTSTP
trap -- '' SIGTTIN
trap -- '' SIGTTOU
-------------
6178
trap -- 'echo bye' EXIT
trap -- '' SIGTSTP
trap -- '' SIGTTIN
trap -- '' SIGTTOU
-------------
6180

Почему подоболочка подстановки команд ведет себя по-разному в том смысле, что она утверждает, что унаследовала расположение ловушек (за исключением того, что она фактически не следует за ними)?

PSkocik
источник

Ответы:

2

Интересно. Это похоже на поведение Bash.

Я попробовал 3 других POSIX-совместимых оболочки (zsh, dash, busybox), и во всех них был получен echo "$(trap)"тот же результат, что и (trap): запускается подоболочка, а подоболочка не показывает EXITловушку.

(Обратите внимание, что trap -pэто специфично для Bash, и без дополнительных параметров он делает то же самое, что trapи без параметров.)

Поведение Bash потенциально полезно : это означает, что вы можете писать a="$(trap)"для захвата настроек ловушек родительской оболочки, которые, скорее всего, будут интересны.

Однако, если вы устанавливаете или очищаете ловушку в подоболочке, тогда она будет перечислять ловушки подоболочки вместо родительской:

$ trap 'echo bye' EXIT
$ echo "$(trap TERM; trap)"  # explicitly clear TERM, but leave EXIT alone
trap -- '' SIGTSTP
trap -- '' SIGTTIN
trap -- '' SIGTTOU

Таким образом, они также рассмотрели редкий случай, когда вы заинтересованы в ловушках подоболочки.

В общем, я заметил, что разработчики Bash, похоже, приложили дополнительные усилия для того, чтобы работа с подоболочками работала хорошо. Также намного проще управлять фоновыми подпроцессами с помощью Bash, чем с более минимальными оболочками POSIX.

Jander
источник