使用crontab停止python脚本

时间:2015-02-19 19:11:27

标签: python crontab

如果我使用此crontab每隔十二小时启动一个python脚本:

0 1,13 * * * /usr/bin/python script.py

然后如何停止在中间运行的脚本?

即。我希望python脚本在凌晨1点和下午1点开始,但是在早上6点和下午6点停止脚本。

我这样做是为了解决这样一个事实,即制作一个特定的剧本我每天睡6到12小时就证明了这一点!将过程交给系统本身似乎更好。

3 个答案:

答案 0 :(得分:1)

一种方法是让您的Python脚本在启动时在已知路径上将其PID写入文件系统,然后在退出时删除PID文件。然后,您可以在上午6点/下午安排一个cron作业来运行一个脚本,该脚本使用PID向Python进程发送终止信号 - 让脚本看起来像:

# Let's say this is in "kill_python.sh"
kill `cat /path/to/my/pidfile`

然后你的crontab条目看起来像:

0 6,18 * * * /bin/bash /path/to/kill_python.sh

或者,一种远不那么精确且不太优选的方法可能是询问流程表以寻找该流程。如下所示:

# Alternate implementation of "kill_python.sh"
kill `ps a | grep python script\.py | grep -v grep | awk '{ print $1 }'`

但这更容易出错,我赞同第一种方法远不止这一种方法。我把它包括在内以防由于某种原因在启动时无法捕获Python进程的PID。

答案 1 :(得分:1)

我认为我想在python中使用这种方法,因为你说你查看crontab的唯一原因是因为你无法弄清楚如何在python中这样做。

我正在使用库apscheduler,它允许您稍后安排python脚本运行时间。

这是一个为1a或1p(以下一个为准)安排作业并将分别以6a或6p结束的示例。作业完成后,再次调用main()来安排下一个作业:

import datetime
from apscheduler.schedulers.background import BackgroundScheduler

def job_function():
    """Worker function that will be called at 1a or 1p everyday"""
    while True:
        if datetime.datetime.now().time() >= endtime:
            main()
            break

def main():
    """Main function that determines what time it is and when job_function() should be run next"""
    earlystart = datetime.time(hour=1)
    latestart = datetime.time(hour=13)
    now = datetime.datetime.now()
    global endtime
    if earlystart < now.time() > latestart:
        tomorrow = now.date() + datetime.timedelta(days=1)
        startdate = now.replace(day=tomorrow.day, hour=earlystart.hour, minute=0, second=0, microsecond=0)
        endtime = datetime.time(hour=6)
    else:
        if datetime.datetime.now() < earlystart:
            starthour = earlystart
            endtime = datetime.time(hour=6)
        else:
            starthour = latestart
            endtime = datetime.time(hour=18)
        startdate = now.replace(hour=starthour.hour, minute=0, second=0, microsecond=0)
    scheduler.add_job(job_function, 'date', run_date=startdate)

if __name__ == '__main__':
    scheduler = BackgroundScheduler()
    scheduler.start()
    main()

如果您有任何问题,请与我们联系。

答案 2 :(得分:1)

我认为你可以写一个新的shell脚本来杀死你的python脚本并向crontab添加一个新行,如下图所示。

0 6,18 * * * /usr/bin/sh killPythonScript.sh

要杀死python脚本,你需要知道脚本的pid。为了获得此信息,您可以在新的shell脚本中调用脚本并获取pid。将其写入文件,然后当您要从文件中删除进程读取pid时。

或者尝试使用其名称来杀死脚本的更简单方法。例如,killPythonScript.sh应该如上所述

killall -g script.py

或者您可以将此行直接添加到您的crontab

0 6,18 * * * /usr/bin/sh killall -9 script.py

我试着说清楚。我希望它对你有所帮助。