Родительская ловушка видима, но не запускается подоболочкой - PullRequest
1 голос
/ 22 марта 2019

Проверено на Bash 5.0.2

В соответствии с GNU Bash Справочное руководство ,

Bash выполняет расширение [подстановки команд], выполняя команду [] в среде подоболочек

Согласно Базовые спецификации открытых групп, выпуск 6 :

при вводе подоболочки для ловушек, которые не игнорируются, устанавливаются действия по умолчанию.


Так что при запуске следующего скрипта:

function a {
   trap -p EXIT
}

trap "echo 'parent'" EXIT

echo "$(a)"
(a)

trap - EXIT

echo 'exiting'

... я ожидал бы вывод:

exiting

... но вместо этого я получаю:

trap -- 'echo '\''parent'\''' EXIT
trap -- 'echo '\''parent'\''' EXIT
exiting

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


Что здесь происходит?

Ответы [ 2 ]

2 голосов
/ 22 марта 2019

Вы, кажется, читаете старую версию спецификации.В самом последнем ,

Когда вводится подоболочка, для ловушек, которые не игнорируются, должны быть установлены действия по умолчанию, за исключением случая замены команды, содержащейтолько одна команда ловушек, когда ловушки не нужно изменять.

1 голос
/ 22 марта 2019

Вы заметите, что ловушки срабатывают точно в соответствии со спецификацией.Это просто вывод из trap, который является неожиданным.

Это особенность Bash 4.2 ( примечания к выпуску ):

b.  Subshells begun to execute command substitutions or run shell functions or
    builtins in subshells do not reset trap strings until a new trap is
    specified.  This allows $(trap) to display the caller's traps and the
    trap strings to persist until a new trap is set.

Обычно люди принимают этокак должное.Рассмотрим этот совершенно неудивительный обмен Bash:

bash$ trap
trap -- 'foo' EXIT
trap -- 'bar' SIGINT

bash$ trap | grep EXIT
trap -- 'foo' EXIT

Теперь посмотрим на результат в других оболочках, таких как Dash, Ksh или Zsh:

dash$ trap
trap -- 'foo' EXIT
trap -- 'bar' INT

dash$ trap | grep EXIT
(no output)

Возможно, это более правильно, но я сомневаюсь, что многиелюди ожидают этого.

...