为何后台运行的bash子脚本b.sh仅输出首条counting后无后续迭代输出
现象原因
该问题的核心触发因素是Linux终端对后台进程的输出限制机制:
- 你在交互式终端中执行
./a.sh时,终端默认开启tostop配置,后台进程组的进程尝试向控制终端写入stdout/stderr时,内核会向该进程发送SIGTTOU信号,信号默认行为是暂停进程运行。 - 第一条
counting能正常输出的原因:./b.sh &启动后,前台进程组仍归属a.sh本身,b.sh的第一次echo执行发生在some-long-operation-binary启动之前,未触发后台输出限制,因此内容正常打印。当a.sh启动some-long-operation-binary后,该二进制程序成为新的前台进程组所有者,b.sh作为后台进程下一次执行echo尝试写终端时,立刻收到SIGTTOU信号被暂停,因此不会再有后续输出,也不会继续执行循环。
b.sh运行状态说明
- 你给出的示例场景中,b.sh已经被
SIGTTOU信号暂停,不会继续迭代运行,执行ps aux | grep b.sh可以看到进程状态为T(停止状态)。 - 你补充的实际使用场景中,如果b.sh后续所有输出都写入文件、不再往stdout/stderr(控制终端)输出内容,就不会触发
SIGTTOU信号,b.sh会正常迭代运行,完成轮询检测和文件写入逻辑。
可选修复方案(如果需要b.sh持续输出到终端)
- 方案1:运行a.sh前关闭终端的SIGTTOU限制,执行
stty -tostop,执行完成后可以用stty tostop恢复默认配置 - 方案2:启动b.sh时将输出重定向到文件,避免写入控制终端:
./b.sh > b.log 2>&1 & - 方案3:用
nohup启动b.sh,默认将输出写入nohup.out文件:nohup ./b.sh &
内容的提问来源于stack exchange,提问作者unsafe_where_true
相关产品推荐
相关产品推荐

