本文介绍了捕集阱在管道输送时是否按预期工作?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

以下是用于问题演示的最少代码: http://pastebin.com/5TXDpSh5

Here is minimal code for issue demonstration:http://pastebin.com/5TXDpSh5

#!/bin/bash
set -e
set -o pipefail

function echoTraps() {
    echo "= on start:"
    trap -p
    trap -- 'echo func-EXIT' EXIT
    echo "= after set new:"
    trap -p
    # we can ensure after script done - file '/tmp/tmp.txt' was not created
    trap -- 'echo SIG 1>/tmp/tmp.txt' SIGPIPE SIGHUP SIGINT SIGQUIT SIGTERM
}

trap -- 'echo main-EXIT1' EXIT

echo "===== subshell trap"
( echoTraps; )

echo "===== pipe trap"
echoTraps | cat

echo "===== done everything"

输出

===== subshell trap
= on start:
= after set new:
trap -- 'echo func-EXIT' EXIT
func-EXIT
===== pipe trap
= on start:
= after set new:
trap -- 'echo func-EXIT' EXIT
===== done everything
main-EXIT1

预期产量

===== subshell trap
= on start:
= after set new:
trap -- 'echo func-EXIT' EXIT
func-EXIT
===== pipe trap
= on start:
= after set new:
trap -- 'echo func-EXIT' EXIT
func-EXIT                 <---- here is the expected difference
===== done everything
main-EXIT1

注意:我已针对OSX 10.9.2 bash(3.2.51)进行了测试-其他版本的bash在实际预期输出之间具有相同的区别,并描述了

NB: i tested for OSX 10.9.2 bash (3.2.51) - other versions of bash has same difference between actual an expected output, and described bellow

推荐答案

找出此行为是否可预期的唯一方法是询问Chet Ramey(GNU bash维护者).请发送包含您的报告的电子邮件至[email protected]

The only way to find out if this behavior is expected or not is to ask Chet Ramey (GNU bash maintainer). Please send an email with your report to [email protected]

您可以看到,当前的行为似乎是正确的,因为它可以在以下方式显式处理subshel​​l情况: http://git.savannah.gnu.org/cgit/bash.git/tree/execute_cmd.c#n621

You can see that the current behavior seems to be correct, given that it handles the subshell case explicitly in: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);

如您所见,显式子Shell大小写被作为特殊情况处理(命令分组的情况也是如此).正如Adrian所发现的,由于多种错误报告,这种行为在历史上已经发展起来.

As you can see, the explicit subshell case is handled as a special case (and so is the case with the command grouping). This behavior has evolved historically, as Adrian found out, due to multiple bug reports.

这是此特定功能(触发子外壳上的EXIT陷阱)的更改列表:

This is the list of changes for this particular feature (triggering EXIT trap on subshells):

提交: 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 (回复:等待期间不会触发管道子外壳中的EXIT陷阱)

Report: https://lists.gnu.org/archive/html/bug-bash/2013-04/msg00126.html (Re: trap EXIT in piped subshell not triggered during wait)

提交: 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 (退出陷阱,管道和子外壳)

Report: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=698411 (EXIT trap and pipeline and subshell)

提交: 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 (交互式shell中的退出陷阱)

Report: http://lists.gnu.org/archive/html/bug-bash/2012-07/msg00084.html (EXIT traps in interactive shells)

最近还有一个关于未在某些预期的上下文中执行EXIT陷阱的错误报告: http://lists.gnu.org/archive/html/bug-bash/2016-11/msg00054.html

There is also a recent bug report in relation to the EXIT trap not executing in some expected contexts: http://lists.gnu.org/archive/html/bug-bash/2016-11/msg00054.html

这篇关于捕集阱在管道输送时是否按预期工作?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-05 17:28
查看更多