请解释这些陷阱输出:
$ 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
Run Code Online (Sandbox Code Playgroud)
为什么命令替换子 shell 的行为不同,因为它声称继承了陷阱处置(除了它实际上并不遵循它们)?
有趣的。这似乎是 Bash 特有的行为。
我尝试了其他 3 个 POSIX 兼容 shell(zsh、dash、busybox),所有这些 shell 都echo "$(trap)"给出了相同的结果(trap):运行了一个子 shell,并且该子 shell 不显示陷阱EXIT。
(请注意,这是 Bash 特有的,如果没有额外的参数,它会执行与没有参数trap -p相同的操作。)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
Run Code Online (Sandbox Code Playgroud)
因此,他们还介绍了您对子 shell 的陷阱感兴趣的罕见情况。
总的来说,我注意到 Bash 开发人员似乎付出了一些额外的努力来使子 shell 处理良好地工作。使用 Bash 管理后台子进程也比使用更简单的 POSIX shell 更容易。