我的设置与许多类似的查询共享成分,但似乎有一个独特的问题。它。
我在命令行上运行了一个冗长的 PHP 进程,并输出到标准输出。它足够长我想在后台运行它,同时通过日志文件实时监控它的输出,所以我将它的输出定向到一个文件(>> log.out)并将它从终端分离并在后台运行与nohup。最后,我想确保进程在崩溃或我的服务器重新启动时重新启动,所以我有一个 cron 作业,它定期执行一个 shell 脚本,检查进程是否已经在运行,如果没有,则启动它。这是 bash 脚本的相关部分:
now=$(date)
echo "restarting daemon at $now"
nohup php /home/me/code/daemon.php >> /home/me/logs/daemon.log &
如果我自己从命令行执行脚本,它会很好地工作:它会在后台启动进程,并且进程会不断地将其记录到 daemon.log 中,我可以在其中对其进行检查。这是我使用的命令行(*):
/bin/bash /home/me/code/tickle_daemon.sh >> /home/me/logs/tickle_daemon.out 2>&1
但是,如果我从 cron 执行完全相同的命令,那么 php 进程的输出会被缓冲,并且不会出现在 daemon.log 中,直到进程退出或被杀死(此时进程生成的所有输出都会立即出现)。请注意,在这两种情况下,实际进程都是在后台匿名运行的;区别仅在于将该进程启动到后台的 shell 脚本本身是从交互式命令行运行还是从 shell 脚本运行。
所以我的问题是: cron 和 shell 脚本的命令行执行有什么不同,我怎样才能强制这个事件链保持我最里面的进程的输出不缓冲?
就我所尝试的而言,按照此处的建议,我尝试使用 stdbuf 通过在各种事物上加上前缀“stdbuf -o0 -e0”来关闭缓冲,包括
- 我的 nohup 命令中的 php 调用
- 我的 shell 脚本中的 nohup 调用
- 我的 cron 选项卡中的 shell 脚本调用
但是这些都没有消除我看到的缓冲。
我还探索了 php 自己的缓冲区刷新命令(例如,flush()),但这些也没有效果。我自己对文档的解释是这些应该是无关紧要的;在命令行调用( https://www.php.net/manual/en/outcontrol.configuration.php)中输出缓冲总是关闭的。
任何人都可以帮忙吗?
谢谢,尼克
(* 是的,我知道我将 shell 脚本输出记录到一个文件以及守护程序的输出到另一个文件。这样我就可以跟踪守护程序需要重新启动的频率。缓冲不是这一秒的问题日志文件,因为 shell 脚本在每次 cron 时都会立即完成;它只是内部 PHP 进程,它不会立即完成,它的输出在某处被停止。)