有人会提供 Bash 同步与异步作业的示例吗?

Zhr*_*hro 9 bash

根据 Bash 4.4 更新日志:

https://lists.gnu.org/archive/html/info-gnu/2016-09/msg00008.html

bash-4.3 和 bash-4.4 之间有一些不兼容的变化。Bash 现在仅保留异步作业的退出状态,而不是所有作业。这意味着不可能使用“wait”来检索先前完成的同步命令的状态。

https://fossies.org/diffs/bash/4.3.46_vs_4.4/CHANGES-diff.html

Bash 仅将异步命令添加到它记住其状态的后台 pid 表中,以避免在创建和获取大量子进程的脚本期间它变得过大。这意味着 `wait' 不再适用于同步作业,但 $? 在这些情况下可用于获取退出状态。

我已经被 4.3 和 4.4 之间的其他一些重大更改所困扰,但我不知道如何编写一个测试此特定更改的示例。

Bash 中的同步作业与异步作业有什么区别,它在哪里存储等待查询的 pid 表?

Sté*_*las 3

例子:

4.3

bash-4.3$ (echo "$BASHPID"; exit 123)
5358
bash-4.3$ wait 5358; echo "$?"
123
Run Code Online (Sandbox Code Playgroud)

4.4

bash-4.4$ (echo "$BASHPID"; exit 123)
12171
bash-4.4$ wait 12171
bash: wait: pid 12171 is not a child of this shell
Run Code Online (Sandbox Code Playgroud)

您不能再使用wait来获取在前台(同步)运行的子 shell 的退出状态。前台是指交互式 shell 的作业,但这同样适用于在非交互式 shell 中运行的命令。

请注意,它也适用于稍后通过以下方式放入前台的后台作业fg

bash-4.4$ (sleep 10; exit 123) &
[1] 12857
bash-4.4$ fg
( sleep 10; exit 123 )
bash-4.4$ wait 12857
bash: wait: pid 12857 is not a child of this shell
Run Code Online (Sandbox Code Playgroud)

withbash-4.3和 beforebash会记住每个过去的后台和前台命令的退出状态。这对于前台命令没有用,因为通常您不知道脚本中的 pid,也不知道以下内容:

cmd1 &
...
cmd2
wait "$!"
Run Code Online (Sandbox Code Playgroud)

cmd1的 pid 很可能已被重用cmd2。在这种情况下,wait "$!"您将获得退出状态cmd2而不是cmd1wait仅记录异步命令的 pid 可以稍微降低为您提供错误命令的退出状态的风险(除了 @Christopher 提到的性能问题之外)。