使用 crontab 停止 python 脚本

Stop python script with crontab

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

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

那我如何停止中间的脚本 运行?

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

我这样做是为了解决这样一个事实,即制作一个我必须每天睡 6-12 小时的特定脚本证明我无法做到!好像把过程交给系统自己处理比较好

一种方法是让您的 Python 脚本在启动时将其 PID 写入已知路径的文件系统,然后在退出时删除 PID 文件。然后,您可以在 6 am/pm 到 运行 安排一个 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

或者,一种不太精确且不太可取的方法可能是询问进程 table 以查找该进程。类似于以下内容:

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

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

我想我会在 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()

如果您有任何问题,请告诉我。

我认为您可以编写一个新的 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

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