我的剧本:
./app 2&>1 | ./pipelog --filename=run.log
我使用pipelog来旋转应用程序的stdout、stderr日志。我测试了它,当发送SIGTERM到脚本在关机期间,两个进程同时接收信号:
由此产生的问题是,应用程序的最后一个日志不见了。如何实现pipelog在app退出后退出?我现在只能在管道日志里睡固定的时间,这并不优雅。
flseospp1#
这可能会起作用:
./app 2&>1 | (trap '' TERM; exec ./pipelog --filename=run.log)
这样,pipelog就应该忽略SIGTERM并继续运行,直到它在其输入管道上到达EOF,这将在app退出时发生。我假设app和pipelog都是内部程序,所以我不能完全确定这是否可行,但我可以想到以下几个失败案例,以及如何处理它们:1.如果app启动了共享其stdout或stderr的守护进程子进程,但没有关闭,那么它们将无限期地保持pipelog的活动状态。如果是这种情况,并且您无法在app中修复它,那么解决方案可能涉及使用PR_SET_CHILD_SUBREAPER的 Package 程序。1.如果pipelog在EOF时不退出,那么它将无限期地保持活动状态。任何解决方法都必然会涉及争用条件,因此如果是这种情况,您应该在pipelog的代码中修复它。1.如果pipelog为SIGTERM设置了一个信号处理程序,它将覆盖上面的trap,并继续执行以前的操作。如果是这种情况,并且您无法禁用它,那么解决方案可能包括在外部bash脚本中捕获SIGTERM,并手动将其仅发送到app。
pipelog
SIGTERM
EOF
app
PR_SET_CHILD_SUBREAPER
trap
1条答案
按热度按时间flseospp1#
这可能会起作用:
这样,
pipelog
就应该忽略SIGTERM
并继续运行,直到它在其输入管道上到达EOF
,这将在app
退出时发生。我假设
app
和pipelog
都是内部程序,所以我不能完全确定这是否可行,但我可以想到以下几个失败案例,以及如何处理它们:1.如果
app
启动了共享其stdout或stderr的守护进程子进程,但没有关闭,那么它们将无限期地保持pipelog
的活动状态。如果是这种情况,并且您无法在app
中修复它,那么解决方案可能涉及使用PR_SET_CHILD_SUBREAPER
的 Package 程序。1.如果
pipelog
在EOF时不退出,那么它将无限期地保持活动状态。任何解决方法都必然会涉及争用条件,因此如果是这种情况,您应该在pipelog
的代码中修复它。1.如果
pipelog
为SIGTERM
设置了一个信号处理程序,它将覆盖上面的trap
,并继续执行以前的操作。如果是这种情况,并且您无法禁用它,那么解决方案可能包括在外部bash脚本中捕获SIGTERM
,并手动将其仅发送到app
。