【发布时间】:2015-01-26 04:40:32
【问题描述】:
我有一个 bash 脚本(我正在转换为 perl),它在无限循环 (while true; do) 中运行,以轮询我们网络上的设备并将它们的响应记录到文本文件中。在 (while) 循环的每次迭代中,该设备的文本文件都会附加其最新信息。
我想让这个脚本始终运行——如果它挂起、崩溃或不再写入适当的文本文件——应该重新启动它。
按照this StackOverflow 问题中发布的建议,我可以编写以下 bash 脚本:
until myserver; do
echo "Server 'myserver' crashed with exit code $?. Respawning.." >&2
sleep 1
done
其中myserver 是轮询程序。这将解释脚本意外崩溃或挂起的问题,假设在这些情况下发出了非零退出代码。但是,如果脚本没有完全失败/退出,但失败的方式只是阻止它写入文本文件——在这种情况下,我也想重新启动脚本。这就是类似看门狗的脚本的用武之地。我可以使用 Python 的 watchdog 并编写一个脚本,该脚本使用 Observer 库来监视正在生成的文本文件 like in this example。我会触发停滞的文本文件来为 python 脚本发出非零退出,然后按如下方式扩充上述 bash 脚本:
until [myserver -o pythonMon]; do
echo "Server 'myserver' crashed with exit code $?. Respawning.." >&2
sleep 1
done
其中pythonMon 是监控文本文件是否正确更新的python 脚本。不幸的是,这种方法需要三个脚本(主轮询脚本和两个监控脚本);这有点杂乱无章。我正在寻找优化/简化这种方法。有什么建议吗?理想情况下,我有一个脚本(至少一个监控脚本)来保持轮询脚本运行而不是两个。有没有办法将文件监控直接添加到 bash 或 perl 代码中?
这是在 64 位 CentOS 6.5 上运行的
【问题讨论】:
-
我认为投票之间存在某种暂停。如何从程序中取出循环,以便它只询问硬件一次,记录结果并退出。然后您可以将其作为
cron作业运行,该作业将以相同的频率运行,并且不会出现重新启动的问题。如果轮询失败,会发生的只是数据序列中缺少一个条目。 -
@Borodin 有一个暂停,但轮询每 10 秒发生一次,因此 cron 作业不起作用,因为它只允许脚本每分钟执行一次(需要 10 秒) .
-
那么你的 Perl 程序应该每十秒
fork一个子 Perl 进程并让它轮询。父进程可以kill并在生成一个新子进程之前收获最新的子进程,尽管您需要重新启动 “如果 [进程] 不再写入适当的文本文件”令人担忧。您在这里想象什么样的错误,如何对其进行测试?我会用一些示例代码写一个答案,但我目前使用的是平板电脑,无法测试任何东西。 -
@Borodin 谢谢。我不太熟悉在 perl 中分叉子进程,但会查找它。至于没有正确写入文件的错误,我还不确定根本原因,但已经看到轮询 bash 文件的 PID 仍然存在,但输出文本文件不再更新的情况。这导致我监控这些文本文件的写入,如果它们停滞不前则重新启动。我假设它可能是网络中的一个小问题或一个失败的轮询设备,并且由于某种原因停止了轮询脚本。这有意义吗?