设置 cron 作业以检查长期运行的进程是否仍在进行,如果没有,启动它的最佳方法是什么?

Ben*_*Ben 5 linux unix process cron

根据标题:

设置 cron 作业以检查长期运行的进程是否仍在进行,如果没有,启动它的最佳方法是什么?

如果我在 cron 中启动一个长时间运行的进程,它会阻塞吗?还是 cron 作为一个独立的孩子分叉这个过程?

谢谢!

Ama*_*rus 5

一个常见的习惯用法是长时间运行的进程有一个 pid 文件。基本上是一个文件/var/run或类似的文件,它只有程序的 pid 或进程 id。当程序启动时,它把文件放在那里,当它停止时,它删除文件。您可以通过查看该文件是否存在来轻松检查该程序是否存在。

这也可用于查看程序是否崩溃。如果文件在那里,但没有进程使用该 pid 运行,则程序停止,但没有删除 pid 文件,即它崩溃了。在这种情况下,您可以删除 pid 文件并重新启动程序。然而,这并不是万无一失的,因为有时 PID 可能会被在原始进程崩溃后启动的新进程重用。


小智 5

设置 cron 作业以检查长期运行的进程是否仍在进行,如果没有,启动它的最佳方法是什么?

一个简单的方法是使用一个简单的脚本来检查进程是否正在运行,然后在必要时重新启动它。

(有时最好通过“虚拟事务”来实际验证进程是否正在运行,例如为了验证 SMTP 进程,您可能会建立 TCP 端口连接并检查它是否正确响应。)

但是请注意您作为交互式用户以及 cron(8) 何时运行您的脚本之间的环境差异。

回答你问题的第二点:

如果我在 cron 中启动一个长时间运行的进程,它会阻塞吗?还是 cron 作为一个独立的孩子分叉这个过程?

cron(8) 将 fork 执行 cron 作业,但除非您的脚本或进程“分离”,否则 cron 会将其作为子进程维护,直到它退出(这就是 cron 能够从 stderr 收集所有输出,并通过电子邮件。)

但是,我想您在想,您真的可以从 cron 运行长期运行的过程吗?如果这样做,您需要确保它只能启动自己的一个副本,并且如果它已经在运行,它将快速退出。

保持长时间运行的进程运行的更好解决方案 - 如果您只担心退出或崩溃

  • 如果您的进程可以保持连接,请通过 inittab(5) 和 'respawn' 选项使用 init(1)。通常甚至守护进程也有“无分叉”选项。
  • 或者,如果您的操作系统没有 inittab 功能或您无权访问它,请使用 DJB 的daemontools 之类的工具
  • 如果您有幸使用 Solaris 10 或 OpenSolaris,则可以使用 SMF。(这甚至可以与执行 fork 和 detach 的进程一起使用。)
  • 如果是您自己的代码,您可以将其编写为具有父/子进程对,父进程在收到 SIGCHLD 时重新启动子进程。