![有人可以提供 Bash 同步与异步作业的示例吗?](https://linux22.com/image/103037/%E6%9C%89%E4%BA%BA%E5%8F%AF%E4%BB%A5%E6%8F%90%E4%BE%9B%20Bash%20%E5%90%8C%E6%AD%A5%E4%B8%8E%E5%BC%82%E6%AD%A5%E4%BD%9C%E4%B8%9A%E7%9A%84%E7%A4%BA%E4%BE%8B%E5%90%97%EF%BC%9F.png)
根据 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 提到的性能问题之外)。