Единственный способ узнать, ожидается ли такое поведение, — это спросить Чета Рэми (сопровождающего GNU bash). Отправьте электронное письмо с отчетом на адрес [email protected].
Вы можете видеть, что текущее поведение кажется правильным, учитывая, что он явно обрабатывает случай подоболочки в: http://git.savannah.gnu.org/cgit/bash.git/tree/execute_cmd.c#n621
/* We want to run the exit trap for forced {} subshells, and we
want to note this before execute_in_subshell modifies the
COMMAND struct. Need to keep in mind that execute_in_subshell
runs the exit trap for () subshells itself. */
/* This handles { command; } & */
s = user_subshell == 0 && command->type == cm_group && pipe_in == NO_PIPE && pipe_out == NO_PIPE && asynchronous;
/* run exit trap for : | { ...; } and { ...; } | : */
/* run exit trap for : | ( ...; ) and ( ...; ) | : */
s += user_subshell == 0 && command->type == cm_group && (pipe_in != NO_PIPE || pipe_out != NO_PIPE) && asynchronous == 0;
last_command_exit_value = execute_in_subshell (command, asynchronous, pipe_in, pipe_out, fds_to_close);
if (s)
subshell_exit (last_command_exit_value);
else
sh_exit (last_command_exit_value);
Как видите, явный случай подоболочки обрабатывается как особый случай (как и случай с группировкой команд). Как выяснил Адриан, такое поведение исторически сложилось из-за многочисленных сообщений об ошибках.
Это список изменений для этой конкретной функции (срабатывание ловушки EXIT на подоболочках):
Коммит: http://git.savannah.gnu.org/cgit/bash.git/commit/?id=a37d979e7b706ce9babf1306c6b370c327038eb9
+execute_cmd.c
+ - execute_command_internal: make sure to run the EXIT trap for group
+ commands anywhere in pipelines, not just at the end. From a point
+ raised by Andreas Schwab <[email protected]>
Отчет: https://lists.gnu.org/archive/html/bug-bash/2013-04/msg00126.html (Re: ловушка EXIT в конвейерной подоболочке не срабатывает во время ожидания)
Коммит: http://git.savannah.gnu.org/cgit/bash.git/commit/?id=1a81420a36fafc5217e770e042fd39a1353a41f9
+execute_cmd.c
+ - execute_command_internal: make sure any subshell forked to run a
+ group command or user subshell at the end of a pipeline runs any
+ EXIT trap it sets. Fixes debian bash bug 698411
+ http://bugs.debian.org/cgi-big/bugreport.cgi?bug=698411
Отчет: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=698411 (ловушка EXIT, конвейер и подоболочка)
Коммит: http://git.savannah.gnu.org/cgit/bash.git/commit/?id=fd58d46e0d058aa983eea532bfd7d4c597adef54
+execute_cmd.c
+ - execute_command_internal: make sure to call subshell_exit for
+ {} group commands executed asynchronously (&). Part of fix for
+ EXIT trap bug reported by Maarten Billemont <[email protected]>
Отчет: http://lists.gnu.org/archive/html/bug-bash/2012-07/msg00084.html (ловушки EXIT в интерактивных оболочках)
Существует также недавний отчет об ошибке, связанный с тем, что ловушка EXIT не выполняется в некоторых ожидаемых контекстах: http://lists.gnu.org/archive/html/bug-bash/2016-11/msg00054.html.
person
dualbus
schedule
13.01.2017
function foo() {
сочетает синтаксис POSIX sh и ksh88 таким образом, что ни один из них не совместим. Лучше использовать либоfoo() {
(маршрут POSIX), либоfunction foo {
(маршрут ksh, хотя обратите внимание, что bash не реализует специальную семантику для функций, объявленных таким образом, которую имеет ksh, что делает этот синтаксис несколько вводит в заблуждение читателей, которые могут ожидать локальные переменные по умолчанию и т. д.). - person Charles Duffy   schedule 27.01.2018