使用 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
我试着说清楚。我希望它对你有帮助。
如果我使用这个 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
我试着说清楚。我希望它对你有帮助。