繁体   English   中英

为什么陷阱在管道中不起作用

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM