【发布时间】:2017-01-27 17:53:45
【问题描述】:
我有一个名为批处理启动器的 bash 脚本在工作。它负责启动和报告各个批次的状态。批次的启动是这样完成的:
env $BENV setsid $BATCH $OPT >> $FILE 2>&1
几个月前,我遇到了一个问题,一个带有分叉子节点的批次在 PGID 上发送了一个终止信号,最终杀死了该批次和批次启动器,这是一个很大的禁忌。我对该问题的解决方案是添加 setsid 部分(因为 bash 不允许 setpgrp),这会创建一个新会话并因此创建一个新的 PGID。
现在我有另一个问题。与分叉的孩子相同的讨厌批次,除了孩子们在完成工作之前不会写任何日志。在调查了这个问题之后,我发现了原因 here - setsid 产生了一个没有 TTY 的进程,在这种情况下,来自子进程的任何输出都不会在每个换行符上自动刷新,而是在流之前的末尾被刷新一次关闭。这意味着如果一个孩子因错误而死,缓冲区中的日志将永远消失,证明任何调试都是不可能的。
有没有办法告诉setsid 自动刷新 STDOUT/STDERR 输出流?谷歌搜索没有产生任何结果,我目前唯一的解决方案是用支持setpgrp 的语言(如 PERL 或 C)重写批处理启动器,这需要 QA 进行大量测试。
编辑:
小提示,问题可以通过以下方式解决:
env $BENV script -qec "$BATCH $OPT" -af $FILE
这需要早于 2010 年的 util-linux 支持 -e 标志以进行返回代码处理(不幸的是,对于 2005 年的 RHEL5 来说,我不是这种情况,有关详细信息,请参阅 commit)。
【问题讨论】: