Linux 为什么陷阱没有';我不能在管道里工作
在这个脚本中 我们有一个脚本trap.shLinux 为什么陷阱没有';我不能在管道里工作,linux,bash,shell,bash-trap,Linux,Bash,Shell,Bash Trap,在这个脚本中 我们有一个脚本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 #!/bin/bash . trap.sh | : 陷阱没用 有人知道为什么吗?管道左侧的命令在子shell中运行: exit | gre
#!/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
#!/bin/bash
. trap.sh | :
陷阱没用
有人知道为什么吗?管道左侧的命令在子shell中运行:
exit | grep
退出信号陷阱似乎不会传播到子shell
trap 'echo T >&2' EXIT ; (exit) # Nothing.
最好将测试命令更改为
。trap.sh | cat
(trap.sh的标准输出无法与:
一起显示)。但即使这样,也没有输出,所以你是对的:陷阱不起作用。这一定是bash中的一个bug,应该向维护人员报告
有趣的是,当我们从脚本trap.sh内部
echo$$
时,我们看到它是由执行整个管道的同一个shell执行的。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中执行的(为什么,我不知道),而且trap本身从未执行过(我在第二个实验中通过touch
在trap中插入一个文件,而不是仅仅回显,以防继承标准输出时出现问题;该文件从未被触碰过)
根据手册页中对陷阱
命令的描述中的这句话,我猜想在执行源
命令之前,退出
信号会被忽略:
被忽视的信号
无法捕获或重置外壳的入口
因此,执行了
trap
命令,但trap本身从未注册,因此不会启动。是否有脚本运行时,工作目录(cwd)不在脚本所在的位置?@wallyk不,它不在脚本所在的位置。我注意到了子shell问题。但是当我们打电话的时候。trap.sh |::,我想我们在子shell中调用trap.sh,子shell称为trap,当子shell退出时,trap调用应该像调用/trap.sh |::一样调用。我不明白为什么会有不同的结果。$
总是计算父shell的进程ID,即使子进程在不同的进程中执行。+1,因为我认为这可能是一个bug。我用touch trap.fired
替换了echo,以确保这不是标准输出丢失的问题。使用。trap.sh |::
,该文件未创建。尽管bash手册声明:$扩展到shell的进程ID,但显然您是对的,在本例中,$
的计算结果是父shell的进程ID。感谢您的评论,我发现了shell变量BASHPID,手册上说:扩展到当前bash进程的进程id。在某些情况下,这与$$不同,例如不需要重新初始化bash的子shell。实际上,echo$BASHPID
显示了不同的值。