当 pid 不存在时,等待命令起作用

当 pid 不存在时,等待命令起作用

我正面临内置等待的意外行为。

~
❯ sleep 1 &
[1] 72009

~
[1]  + 72009 done       sleep 1

~
❯ wait 72009

~
❯ echo $?
0

尽管 PID 不再存在,但等待仍然以零退出状态退出。

问题

  • 这种行为的原因是什么?
  • 等待是如何进行的?它在幕后做什么?

答案1

在这种情况下, Bashwait返回 0,因为它“记住”进程 72009 是其子进程之一,并且它记住其子进程的退出代码,而退出代码为 0。(文档在这里有些误导,因为它明确提到了“活动”进程.)

在幕后,wait确定给定的进程标识符是否对应于 shell 的子进程之一(可能在作业中);如果是,则检查该进程是否仍在运行。如果它仍在运行,它将等待它完成。完成后,它会确定相应的退出代码(可能仅适用于进程,或适用于整个作业),并返回该退出代码。正确处理信号、进程替换、控制终端等有很多额外的复杂性,但这与这里无关。

退出代码(至少)被记住在作业表中。您可以通过运行具有不同退出代码(false &true &)的两个命令并等待各自的进程标识符来查看其实际情况。只要作业表没有被清除,wait就会给出正确的退出代码。不带参数运行wait以从作业表中删除已完成的作业,您将看到无法再检索早期作业的退出代码。

答案2

这就是waitshell 中内置函数的定义方式。

  • 等待已经终止的子进程会wait导致返回 0。

某些 shell(例如ksh93)具有最后几个进程的缓存,并且可能返回此类子进程的退出代码。

相关内容