crontab如果没有运行则运行python文件

时间:2016-09-14 08:34:10

标签: python crontab

我想通过crontab执行我的python文件,只要它已经关闭或没有运行。我尝试在cron选项卡中添加以下条目,但它不起作用

24 07 * * * pgrep -f test.py || nohup python /home/dp/script/test.py & > /var/tmp/test.out

如果我手动运行pgrep -f test.py || nohup python /home/dp/script/test.py & > /var/tmp/test.out,test.py工作正常,如果我删除pgrep -f test.py ||它也适用于crontab来自我的crontab并保持24 07 * * * nohup python /home/dp/script/test.py & > /var/tmp/test.out

如果我添加pgrep -f,任何想法为什么crontab不起作用?有没有其他方法我可以运行test.py一次,以避免test.py的多个运行进程? 谢谢, 迪帕克

7 个答案:

答案 0 :(得分:3)

通常最好在应用程序中检查应用程序是否正在运行,而不是从外部检查并启动它。管理流程中的流程,而不是期望其他流程执行流程。

  1. 让cron始终运行应用程序
  2. 在应用程序执行开始时,使用锁定文件或类似机制来判断进程是否已在运行。
  3. 如果应用程序已在运行,请在上次测试时更新某个位置并中断新进程。
  4. 如果应用程序未运行,请在某处登录并通知某人(如果需要)并触发流程启动。
  5. 这将确保您可以更好地控制流程的生命周期,并让您决定在发生故障时该怎么做。

    更不用说,如果您想确保应用程序的运行时间很长,最好使用Monit等监控服务。同样,这将取决于您的应用程序添加一个健全层,说明它是否正常。

答案 1 :(得分:2)

pgrep -f在从cron

运行时将自身列为错误匹配

我在script.py运行无限循环的情况下进行了测试。然后

pgrep -f script.py

...从终端提供 一个 pid,13132,同时从cron运行:

pgrep -f script.py > /path/to/out.txt

输出 两个 pid,1313213635

因此,我们可以得出结论,当从cron运行时,命令pgrep -f script.py将自己列为匹配项。不确定如何以及为什么,但最有可能的是,这是由cron以非常有限的一组环境变量(HOME,LOGNAME和SHELL)运行的事实间接引起的。

解决方案

从(包装器)脚本运行pgrep -f会使命令自行列出,即使从cron运行也是如此。随后,从cron

运行包装器
#!/bin/bash

if ! pgrep -f 'test.py'
then
    nohup python /home/dp/script/test.py & > /var/tmp/test.out
# run the test, remove the two lines below afterwards
else
    echo "running" > ~/out_test.txt
fi

答案 2 :(得分:1)

cron可能会看到pgrep -f test.py进程以及test.py进程,从pgrep给出错误的结果。
尝试不使用-f的命令,这应该只是查找test.py或用-f替换-o,这将查找最早出现的事件。

您的另一个选择是在test.py中插入以下内容:

Pid = os.popen('pgrep -f test.py').read(5).strip()

这将允许您检查代码本身,如果它已经在运行。

答案 3 :(得分:0)

遇到这个老问题,我自己在寻找解决方案。

使用psutil

import psutil
import sys
from subprocess import Popen

for process in psutil.process_iter():
    if process.cmdline() == ['python', 'your_script.py']:
        sys.exit('Process found: exiting.')

print('Process not found: starting it.')
Popen(['python', 'your_script.py'])

您还可以使用上一个流程的开始时间来确定它是否运行时间过长而且可能会挂起:

process.create_time()

该流程还有大量其他有用的元数据。

答案 4 :(得分:0)

问题是pgreg -f正在识别cron用来运行命令本身的shell脚本。

我通过在rot13中对文件名进行编码并使用python单行解码来解决pgrep -f问题,因为我不想为cron作业添加脚本包装器。即:

pgrep -f $(python3 -c 'import codecs; print(codecs.decode("grfg.cl", "rot13"))') || nohup python /home/dp/script/test.py & > /var/tmp/test.out

补充:您可以使用tr解码rot13,这将导致更短且更容易阅读的命令:

pgrep -f $(echo grfg.cl | tr a-zA-Z n-za-mN-ZA-M) || nohup python /home/dp/script/test.py & > /var/tmp/test.out

答案 5 :(得分:0)

为什么只检查pid已经像这样运行

Pid = os.popen('pgrep -f myscript.py').readlines()
if len(Pid) > 1:
 exit()

答案 6 :(得分:0)

您可以创建一个名为test.py的测试文件 如果您再次尝试执行同一文件,则应退出。

import time
import os
from tempfile import TemporaryFile
import subprocess


def cron_running(p_name):
    run_cnt=0
    with TemporaryFile() as tf:
        subprocess.call(["ps","ax"], stdout=tf)
        tf.seek(0)
        for line in tf:
            if p_name in line.decode('ascii'):
                run_cnt+=1
    if run_cnt > 1:
        quit()

if cron_running(os.path.basename(__file__)):
    print("cron is already running")
    quit()

for i in range(60):
    time.sleep(1)