击:是陷阱,而管道的工作如预期? [英] Bash: Is trap while piping work as expected?

查看:175
本文介绍了击:是陷阱,而管道的工作如预期?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

下面是最小的code的问题演示:
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庆典(51年2月​​3日) - 庆典的其他版本有实际的预期产出之间的差异一样,并且描述的波纹管

推荐答案

下面有一些更多的测试案例为您的娱乐:

Here are some more test cases for your amusement:

$ cat traps.sh
#!/bin/bash

echoTraps() {
        echo "entering echoTraps()"

        printf "  traps: %s\n" "$(trap -p)"

        echo "  setting trap"
        trap -- 'echo "func-exit()"' EXIT

        printf "  traps: %s\n" "$(trap -p)"

        echo "exiting echoTraps()"
}

trap -- 'echo "main-exit()"' EXIT

echo "===== calling '( echoTraps; )'"
( echoTraps; )
echo

echo "===== calling 'echoTraps | cat'"
echoTraps | cat
echo

echo "===== calling '( echoTraps; ) | cat'"
( echoTraps; ) | cat
echo

echo "===== calling '{ echoTraps; } | cat'"
{ echoTraps; } | cat
echo

的bash-4.2.25(1)

$ ./traps.sh
===== calling '( echoTraps; )'
entering echoTraps()
  traps:
  setting trap
  traps: trap -- 'echo "func-exit()"' EXIT
exiting echoTraps()
func-exit()

===== calling 'echoTraps | cat'
entering echoTraps()
  traps: trap -- 'echo "main-exit()"' EXIT
  setting trap
  traps: trap -- 'echo "func-exit()"' EXIT
exiting echoTraps()

===== calling '( echoTraps; ) | cat'
entering echoTraps()
  traps:
  setting trap
  traps: trap -- 'echo "func-exit()"' EXIT
exiting echoTraps()
func-exit()

===== calling '{ echoTraps; } | cat'
entering echoTraps()
  traps: trap -- 'echo "main-exit()"' EXIT
  setting trap
  traps: trap -- 'echo "func-exit()"' EXIT
exiting echoTraps()

main-exit()

的bash-4.3.0(1)

$ bash-static-4.3.2/bin/bash-static traps.sh
===== calling '( echoTraps; )'
entering echoTraps()
  traps:
  setting trap
  traps: trap -- 'echo "func-exit()"' EXIT
exiting echoTraps()
func-exit()

===== calling 'echoTraps | cat'
entering echoTraps()
  traps: trap -- 'echo "main-exit()"' EXIT
  setting trap
  traps: trap -- 'echo "func-exit()"' EXIT
exiting echoTraps()

===== calling '( echoTraps; ) | cat'
entering echoTraps()
  traps:
  setting trap
  traps: trap -- 'echo "func-exit()"' EXIT
exiting echoTraps()
func-exit()

===== calling '{ echoTraps; } | cat'
entering echoTraps()
  traps: trap -- 'echo "main-exit()"' EXIT
  setting trap
  traps: trap -- 'echo "func-exit()"' EXIT
exiting echoTraps()
func-exit()

main-exit()

底线:不要依赖于边缘的情况下是这样的。我记得有关于子shell和管道调查其他的不一致(不是陷阱),并试图总结我的周围的庆典源$ C ​​$ C头,你不想要走这条路线,并试图了解为什么它的行为就像它在某些情况下确实(在code是真的太可怕了,顺便说一句)。正如你所看到的,有些事情似乎已经被固定和/但两者我的例子已经表现不同比你。

Bottom line: Don't rely on edge-cases like this. I remember investigating other inconsistencies (not about traps) with regards to subshells and pipes and tried to wrap my head around the bash source code and you don't want to go down that route and try to understand why it behaves like it does in certain situations (the code is really horrible, btw). As you can see, some things seem to have been "fixed" and/but both my examples already behave differently than yours.

这篇关于击:是陷阱,而管道的工作如预期?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆