标准子 shell 与命令替换子 shell

标准子 shell 与命令替换子 shell

请解释这些陷阱输出:

$ 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 更容易。

相关内容