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

有人可以提供 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 表?

答案1

例子:

4.3

bash-4.3$ (echo "$BASHPID"; exit 123)
5358
bash-4.3$ wait 5358; echo "$?"
123

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

您不能再使用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

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

cmd1 &
...
cmd2
wait "$!"

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

相关内容