如果你不知道Crontab是什么,它是一个用于Unix和类Unix操作系统的实用工具,允许你在特定时间自动安排和执行任务。Crontab的一个很大优势是,它在崩溃或重启后仍然有效。Crontab条目保存在由cron守护进程读取的文件中,该守护进程在系统启动时自动启动。
本文的目的是使用python-crontab库编写Python程序的执行计划。这个库允许你使用API在操作系统中生成crontab文件,而不必使用特定的操作系统命令。
首先,我们安装该库:
poetry add python-crontab
然后,我们创建一个名为create_crontab.py的文件,并包含以下内容:
if __name__ == '__main__':
cron_tab = CronTab(user=True)
list_cron(cron_tab)
delete_cron(cron_tab)
create_cron(cron_tab)
list_cron(cron_tab)
- cron_tab = CronTab(user=True): 我们创建一个与当前用户crontab关联的CronTab对象。这将允许我们访问和操作计划任务。
- list_cron(cron_tab): 我们将创建一个名为list_cron的函数,用于在屏幕上显示所有计划任务的列表。
- delete_cron(cron_tab): 我们将创建一个函数,用于在创建计划任务之前从crontab中删除所有计划任务。这一步在更新计划定义时非常有用。
- create_cron(cron_tab): 我们将实现一个create_cron函数,用于创建新的计划任务并将它们添加到crontab中。
列出计划任务
我们将CronTab对象传递给此函数并迭代不同的任务。
def list_cron(cron):
for job in cron:
print(job)
删除计划任务
在进行更改时,总是强制crontab写入。
def delete_cron(cron):
cron.remove_all()
cron.write()
创建计划任务
假设我们要安排执行位于以下绝对路径的程序:
/Users/xavierescudero/Projects/tutorial-trading-bot/tutorial_trading_bot/exchange_historical_importer.py
Crontab脚本在后台运行,不在我们的项目内,因此它不知道模块路径。我们需要给它指示:
- 进入根目录:cd /Users/xavierescudero/Projects/tutorial-trading-bot
- 在Poetry管理的虚拟环境中运行模块:poetry run -m tutorial_trading_bot.exchange_historical.importer
- 使用-m选项,Python会在系统搜索目录和当前目录中查找模块,导入它,并像独立脚本文件一样运行它。
模块目录的位置
我们可以使用pathlib从create_crontab.py模块文件的相对路径获取项目的根目录:
from pathlib import Path
PROJECT_DIR_PATH = str(Path(__file__).parent.parent)
并创建到此目录的目录更改命令链:
CD_PROJECT_DIR_COMMAND = ''.join(['cd ', PROJECT_DIR_PATH])
定义要执行的命令
我们创建执行的初始部分,这将用于任何模块:
EXECUTOR_COMMAND = ' '.join(['poetry', 'run python -m tutorial_trading_bot.'])
我们构建了运行每个模块的完整命令(包括目录更改):
EXECUTOR_PATH = ';'.join([CD_PROJECT_DIR_COMMAND, EXECUTOR_COMMAND])
HISTORICAL_IMPORTER_JOB = ''.join([EXECUTOR_PATH, 'exchange_historical_importer', ' &'])
TRADING_BOT_JOB = ''.join([EXECUTOR_PATH, 'trading_bot', ' &'])
定义计划任务
现在我们有了命令,使用python-crontab库的new()函数创建计划任务,并用setall设置cron表达式。
def create_cron(cron):
"""
Check crontab values using https://crontab.guru
"""
cron.new(command=HISTORICAL_IMPORTER_JOB).setall('59 21 * * *') # At 21:59 every day
cron.new(command=TRADING_BOT_JOB).setall('59 22 * * *')
cron.write()
在网站https://crontab.guru上,你可以验证你的cron表达式,并找到大量示例。
重启时执行(无需计划)
当你不在家时,发现Python进程在重启后没有重新启动是一件糟糕的事。这可能很令人沮丧,因为这意味着你的自动化任务或服务没有运行。
我们还可以使用python-crontab库在重启时启动程序:
cron.new(command=TRADING_BOT_JOB).every_reboot()
设置cron任务
我们现在可以从shell安装我们的编程:
poetry run python -m tutorial-trading-bot.create_crontab
我们将在屏幕上看到计划任务的列表:
2024-06-07 00:15:46,872 - __main__ - INFO - Crontab configured
59 21 * * *