![后台子进程会随父进程一起死亡吗?](https://linux22.com/image/127313/%E5%90%8E%E5%8F%B0%E5%AD%90%E8%BF%9B%E7%A8%8B%E4%BC%9A%E9%9A%8F%E7%88%B6%E8%BF%9B%E7%A8%8B%E4%B8%80%E8%B5%B7%E6%AD%BB%E4%BA%A1%E5%90%97%EF%BC%9F.png)
我有一个脚本调用其他几个子脚本。它后来被杀死,这似乎杀死了所有的子脚本。
在大多数情况下,这就是我想要的。但有一两种情况我不想让孩子死。
我想我记得能够通过&
调用脚本时使用 a 来阻止这种情况的发生。
谁能证实这一点吗?
答案1
这里有很多因素需要考虑。请接受这个答案轻微当我凭记忆写下所有这些细节时,我持怀疑态度。 (如果您发现任何错误,请通过编辑或评论纠正我。)
如果使用后台命令&
,然后父 shell 正常退出,则后台命令将继续运行。
但是,如果您以交互方式运行,“后台”命令在尝试读取或写入终端时将被阻止。 (无论父 shell 是否仍在运行,这都适用。)如果 stdout、stdin 和 stderr 被重定向,则这无关紧要。
如果您将命令置于后台,然后您的 SSH 会话断开连接,则后台命令可能会终止。我相信这是因为您的 shell 会将 SIGHUP 发送到其所有子进程,但我不能 100% 确定其细节。
如果您在将某个作业设置为后台后否认该作业(使用内置的 bash disown
),那么它不会仅仅因为您的 SSH 会话终止而终止。但是,尝试写入终端或从终端读取时被阻止的方面仍然适用(对于交互式会话)。
我所知道的最通用的方法是在后台启动子脚本或进程,这样无论生成它的 shell 发生什么情况(并且无论它是交互启动还是从脚本启动),它都不会受到影响,是:
nohup somecommand >/dev/null 2>&1 </dev/null &
这假设您不关心命令的任何输出到其标准输出或标准错误,并且不需要向其提供任何标准输入。
如果您很高兴子脚本继承其父级的文件描述符(即终端不是问题或者您有其他解决方案),那么您真正需要的应该是:
./some-sub-script &
exit
只是附带说明一下,如果您正在编写一个旨在保持运行的守护进程,请(a) 使用日志并 (b) 干净地轮换日志。