使用cronjob运行Python进程,并每分钟检查它是否仍在运行

5

我有一个Python脚本,希望能够通过cronjob定时运行,并每分钟检查一次是否仍在运行,如未运行,则重新启动。

cronjob如下:

/usr/bin/python2.7 /home/mydir/public_html/myotherdir/script.py

关于这个问题有一些相关的信息,但大多数答案并没有清晰详细地描述整个过程,例如:

使用cron job检查Python脚本是否正在运行

例如在那个例子中,它没有说明如何运行初始进程并记录PID。遗憾的是,这让我有很多问题。

因此,有人能给我一个简单的指南来完成这个过程吗?

例如,需要完整的shell脚本,启动脚本的命令等等。


我不会从cron中运行它。我会创建一个服务器进程作为操作系统启动脚本的一部分(在Linux上是Iinit.d),并将其配置为在失败或崩溃时重新启动。我已经有十多年没有这样做了,所以建议尝试使用Stack Exchange Serverfault进行研究。这更像是一个系统管理员的问题。 - LAS
4个回答

8

现在有一种更好的方法来完成这个任务,通过名为flock的实用工具,在单行中直接从cron任务中执行。 flock会在运行应用程序之前获取锁定,并在运行后释放它。格式如下:

* * * * * /usr/bin/flock -n /tmp/fcj.lockfile <your cron job>

对于您的情况,这将是:
* * * * * /usr/bin/flock -n /tmp/fcj.lockfile /usr/bin/python2.7 /home/mydir/public_html/myotherdir/script.py

-n选项表示如果无法获取锁定,则立即失败。还有一个-w <seconds>选项,如果在指定的时间范围内无法获取锁,则会失败。

 * * * * /usr/bin/flock -w <seconds> /tmp/fcj.lockfile <your cron job>

3

这并不难。首先,设置crontab每分钟运行一次检查程序:

* * * * * /home/mydir/check_and_start_script.sh

现在在/home/mydir/check_and_start_script.sh中,
#!/bin/bash
pid_file='/home/mydir/script.pid'
if [ ! -s "$pid_file" ] || ! kill -0 $(cat $pid_file) > /dev/null 2>&1; then
  echo $$ > "$pid_file"
  exec /usr/bin/python2.7 /home/mydir/public_html/myotherdir/script.py
fi

这段代码检查是否存在一个文件,其中包含上次运行脚本的进程ID。如果有,它会读取pid并检查进程是否仍在运行。如果没有,则将当前运行shell的pid放入文件中,并在同一进程中执行python脚本,终止shell。否则,它不会执行任何操作。

不要忘记将脚本设置为可执行。

chmod 755 /home/mydir/check_and_start_script.sh

1
请问scripy.pd是什么? - jainam shah

1
你应该退一步,思考你正在做什么以及为什么要这样做。
你是否真的需要从cron启动你的长时间运行程序?我问这个问题是因为你还需要编写另一个程序(watcher)来启动你的长时间运行程序。希望你能看到,实际上你不需要cron来启动你的长时间运行程序。
所以你现在拥有的是一个watcher每分钟触发并启动long_running程序(如果它没有运行)。
现在你需要真正理解你想要做什么,因为有很多方法可以完成这个任务。如果这是一个练习,watcher可以调用ps并从中确定它是否正在运行并启动它。 在bash中,你可以这样做:
[ -z "$(ps -ef | grep -v grep | grep myprogname)" ] && { echo runit;  }

你只需将myprogname替换为实际名称,并使用启动长时间运行代码的后台命令来运行它 - 例如。但是,你应该使用另一种工具。systemd、daemontools或其他工具。

0
在您的crontab文件中,加入以下代码:
command='/usr/bin/python2.7 /home/mydir/public_html/myotherdir/script.py'

*/1 * * * * pgrep -af "$command" || $command

解释: 每分钟,pgrep 检查 Python 脚本是否已经在运行。如果它正在运行,则不会调用第二个语句,因为我们使用了 ||。如果 pgrep 无法在现有进程中找到 Python 脚本,则将执行第二个语句,并使 Python 脚本重新开始工作。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接