Bash 可以使用 wait
等待它直接启动的进程。但是,如果进程 fork 子进程,然后执行 bash
(也就是说, parent 变成 bash
),新执行的 Bash 进程无法等待“继承的”子进程。这是最小的复制:
#/bin/bash
sleep inf &
pid=$!
exec bash -c "wait $pid;"'echo This shell is $$; sleep inf'
这给出了这个输出:
$ bash test.sh
bash: wait: pid 53984 is not a child of this shell
This shell is 53983
但是,pstree 显示子 pid 确实是 shell 的子进程:
$ pstree -p 53983
bash(53983)─┬─sleep(53984)
└─sleep(53985)
Bash 似乎在内部跟踪生成的进程,并引用此列表而不是调用
waitpid(2)
直接( zsh
有同样的问题,但 ksh
按预期工作)。有什么办法可以解决这种行为,并让 Bash 将“继承的”子项添加到其内部结构中?
最佳答案
我无法重现它,但我写了 a script这表明这种行为在至少 6 个维护良好的 shell(包括提到的 ksh)中是一致的。
正如您在报告中看到的那样,所有 shell 都不会列出被替换的 shell 中的第一个 sleep 作业,只会列出在 exec 调用之后创建的新作业。
调用 exec 时,新 shell 不会继承被替换的 shell 管理的作业列表。这似乎是一种预期的行为,但我在 POSIX 规范中的任何地方都找不到它。
关于Bash:在执行 bash 之前等待产生的子进程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51878331/