[英]Why trap didn't work in a pipeline
在这个脚本中我们有一个脚本trap.sh
#!/bin/bash
trap "echo trapped" EXIT
exit 0
和test.sh. 如果test.sh是这样的
#!/bin/bash
. trap.sh
要么
#!/bin/bash
./trap.sh | :
陷阱工作
但是如果test.sh是这样的话
#!/bin/bash
. trap.sh | :
陷阱不起作用。
谁知道为什么会这样?
更好地将测试命令更改为. trap.sh|cat
. trap.sh|cat
(从标准输出trap.sh
无法与显示:
)。 但即便如此也没有输出,所以你是对的:陷阱不起作用。 这必须是bash中的错误,应该向维护者报告。
有趣的是,当我们从脚本trap.sh内部echo $$
时,我们看到它由执行整个管道的同一个shell执行. trap.sh|cat
. trap.sh|cat
,与手册的语句相矛盾: 管道中的每个命令都作为一个单独的进程执行(即,在子shell中)。 这是一个谬论,请参阅评论。 也许这与最小化子shell创建的一些优化有关,但这只是推测。
我修改了trap.sh
以包含xtrace
选项。
#!/bin/bash
set -x
trap 'echo trapped' EXIT
exit 0
运行trap.sh
作为脚本生成
〜$ ./trap.sh | 猫+陷阱'回声被困'出口+退出0 +被困陷阱被困
然而,首先采购它
~ $ . trap.sh | cat
++ trap 'echo trapped' EXIT
++ exit 0
这表明trap
是在更深的子shell中执行的(为什么,我不知道),并且陷阱本身永远不会被执行(我在第二个实验中通过touch
陷阱中的文件而不是仅仅回显来确认有一个问题,标准输出被继承;文件从未被触及)。
我的猜测是,在执行source
命令之前,以某种方式忽略EXIT
信号,基于手册页中trap
命令描述中的这句话:
进入shell时忽略的信号不能被捕获或重置。
因此,执行trap
命令,但陷阱本身从未注册,因此不会触发。
管道左侧的命令在子shell中运行:
exit | grep
退出sigtrap似乎不会传播到子shell。
trap 'echo T >&2' EXIT ; (exit) # Nothing.
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.