经过Bash 5.0.2测试
Bash通过在子shell环境中执行[the]命令来执行[命令替换]的扩展
根据The Open Group Base Specifications Issue 6:
输入子shell时,不会忽略的陷阱将设置为默认操作。
因此,在运行以下脚本时:
function a {
trap -p EXIT
}
trap "echo 'parent'" EXIT
echo "$(a)"
(a)
trap - EXIT
echo 'exiting'
...我期望输出为:
exiting
...但是我得到了:
trap -- 'echo '\''parent'\''' EXIT
trap -- 'echo '\''parent'\''' EXIT
exiting
......表示功能a
-尽管它正在子外壳中运行-却看到父外壳的trap命令(通过trap -p
)却没有执行。
这是怎么回事?
答案 0 :(得分:2)
您似乎正在阅读该规范的旧版本。在most recent one中,
进入子shell时,除非命令替换仅包含一个陷阱命令,否则不需要更改陷阱,除非是仅包含单个陷阱命令的命令替换,否则应将不被忽略的陷阱设置为默认操作。
答案 1 :(得分:1)
您会注意到陷阱完全根据规范触发。只是trap
的输出是意外的。
这是Bash 4.2(release notes)中的功能:
b. Subshells begun to execute command substitutions or run shell functions or
builtins in subshells do not reset trap strings until a new trap is
specified. This allows $(trap) to display the caller's traps and the
trap strings to persist until a new trap is set.
通常,人们会认为这是理所当然的。考虑一下这种完全毫不奇怪的Bash交换:
bash$ trap
trap -- 'foo' EXIT
trap -- 'bar' SIGINT
bash$ trap | grep EXIT
trap -- 'foo' EXIT
现在在Dash,Ksh或Zsh等其他shell中查看结果:
dash$ trap
trap -- 'foo' EXIT
trap -- 'bar' INT
dash$ trap | grep EXIT
(no output)
这也许更正确,但是我怀疑很多人会期望它。