3

在这个脚本中我们有一个脚本 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 | :

陷阱没有用。

有人知道这是为什么吗?

4

3 回答 3

1

我修改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陷阱中输入文件而不是仅仅回显来确认,以防万一是继承标准输出的问题;该文件从未被触及)。

我的猜测是,根据手册页中命令描述中的这句话,在执行命令EXIT之前以某种方式忽略了信号:sourcetrap

进入 shell 时忽略的信号不能被捕获或重置。

结果,trap命令被执行,但陷阱本身从未注册,因此不会触发。

于 2013-10-15T14:10:24.077 回答
1

最好将您的测试命令更改为. trap.sh|cattrap.sh无法显示标准输出:)。但即使这样也没有输出,所以你是对的:陷阱没有工作。这一定是 bash 中的错误,应该报告给维护人员。

有趣的是,当我们echo $$从脚本 trap.sh 内部时,我们看到它是由执行整个管道的同一个 shell 执行的. trap.sh|cat,这与手册中的说法相矛盾:管道中的每个命令都作为一个单独的进程执行(即,在一个子壳)。 这是一个谬论,请参阅评论。也许这与一些优化以最小化子外壳创建有关,但这只是猜测。

于 2013-10-15T11:33:27.287 回答
0

管道左侧的命令在子 shell 中运行:

exit | grep

出口信号似乎没有传播到子shell。

trap 'echo T >&2' EXIT ; (exit)    # Nothing.
于 2013-07-19T08:21:52.457 回答