![标准子 shell 与命令替换子 shell](https://linux22.com/image/6253/%E6%A0%87%E5%87%86%E5%AD%90%20shell%20%E4%B8%8E%E5%91%BD%E4%BB%A4%E6%9B%BF%E6%8D%A2%E5%AD%90%20shell.png)
请解释这些陷阱输出:
$ line(){ echo -------------; echo $BASHPID; }
$ trap 'echo bye' EXIT; trap -p; line; (trap -p; line); echo "$(trap -p; line)"
trap -- 'echo bye' EXIT
trap -- '' SIGTSTP
trap -- '' SIGTTIN
trap -- '' SIGTTOU
-------------
6176
trap -- '' SIGTSTP
trap -- '' SIGTTIN
trap -- '' SIGTTOU
-------------
6178
trap -- 'echo bye' EXIT
trap -- '' SIGTSTP
trap -- '' SIGTTIN
trap -- '' SIGTTOU
-------------
6180
为什么命令替换子 shell 的行为有所不同,因为它声称继承了陷阱配置(除了它实际上并不遵循它们)?
答案1
有趣的。这似乎是 Bash 特有的行为。
我尝试了其他 3 个 POSIX 兼容 shell(zsh、dash、busybox),所有这些 shell 都echo "$(trap)"
给出了相同的结果(trap)
:运行了一个子 shell,并且该子 shell 不显示陷阱EXIT
。
(请注意,这trap -p
是 Bash 特有的,如果没有额外的参数,它会执行与没有参数相同的操作trap
。)
Bash 的行为可能有用:这意味着您可以编写a="$(trap)"
捕获父 shell 的陷阱设置,这可能更有趣。
但是,如果您在子 shell 中设置或清除陷阱,那么它将要列出子 shell 的陷阱而不是父 shell 的陷阱:
$ trap 'echo bye' EXIT
$ echo "$(trap TERM; trap)" # explicitly clear TERM, but leave EXIT alone
trap -- '' SIGTSTP
trap -- '' SIGTTIN
trap -- '' SIGTTOU
因此,他们还介绍了您对子 shell 的陷阱感兴趣的罕见情况。
总的来说,我注意到 Bash 开发人员似乎付出了一些额外的努力来使子 shell 处理良好地工作。使用 Bash 管理后台子进程也比使用更简单的 POSIX shell 更容易。