【问题标题】:Running a cronjob only one using python-crontab仅使用 python-crontab 运行一个 cronjob
【发布时间】:2015-09-20 09:00:11
【问题描述】:
from crontab import CronTab

tab = CronTab()
cmd1 = 'actual command'

cron_job = tab.new(cmd)
cron_job.minute.every(1)
cron_job.enable()
tab.write_to_user(user=True)

我曾尝试使用 minute.at(1) 在第一分钟运行,但我不知道在固定时间(早上 6 点)运行命令的正确方法是什么,只运行一次......我知道“每个”最终都会重复它,但我不希望那样。需要注意的是我需要使用 python-crontab。

【问题讨论】:

    标签: python cron crontab


    【解决方案1】:

    crontab 语法为:mm hh dd mt wd。因此,将其设置为每天早上 6 点,它将是 00 06 * * * 表示任何一天、一个月、工作日的 06:00(24 小时时间)。如果我正确地引用了documentation,这应该可以工作:

    from crontab import CronTab
    
    tab = CronTab()
    cmd1 = 'actual command'
    
    cron_job = tab.new(cmd)
    cron_job.setall('00 06 * * *')
    cron_job.enable()
    tab.write_to_user(user=True)
    

    【讨论】:

    • 谢谢@heinst 但我想在早上 6 点只运行一次,而不是每天早上 6 点运行一次。
    【解决方案2】:

    linux cron 命令专门设计用于定期运行命令,而 at 命令用于运行一次作业,尽管如果该命令重新提交自身,它可以用于重复运行命令。我不知道将 cron 条目配置为仅执行一次的正常方法,并且找不到任何关于此操作的文档。可以在运行后删除 cron 条目,方法是执行“crontab -e”来编辑 crontab 文件,然后在编辑器中删除作业的条目,或者用“crontab 覆盖 crontab 文件中的所有内容” dev/null' 或使用 'crontab -r' 完全删除 crontab 文件。

    考虑到这一点,我发明了自毁 cron 作业,它是这样的。假设您使用用户名“adhawan”将 cron 作业配置为自己。使作业自毁所需要做的就是使用以下语句作为作业脚本中的最后一条语句:

    crontab -r
    

    这会删除您的 crontab 文件并且应该可以工作,因为您的个人 cron 作业会像您一样运行。我尝试了以下工作,它按预期工作 - 运行一次,然后自行删除!:

    * * * * * echo hello > /var/tmp/cron1; crontab -r
    

    如前所述,Linux/Unix at 实用程序提供了一种在预定时间运行一次的方法。时间由称为 timespec(时间规范)的东西指定。例如,要安排一个作业只在明天早上 6 点运行一次,可以使用以下时间规范

    6 am tomorrow
    

    或在 9 月 18 日早上 6 点进行,可以使用以下方法

    6am Sep 18
    

    或者也指定年份

    6 am 9/18/2015
    

    at's timespec 语法非常灵活。使用最近的术语,它可以称为 DSL(领域特定语言)。它是用 YACC(另一个编译器编译器)实现的,其语法的简化版本可以在它的 timespec 文件中看到,该文件通常安装在 /usr/share/doc/at*/timespec 和在线有它的副本在Abbreviated version of the yacc grammar used by at(1).

    at 可以让作业从使用 -f 选项或从标准输入执行的文件中运行。例如来自名为 atjob 的文件:

    at -f atjob 6 am Sep 18
    

    或从文件重定向的标准输入:

    at 6 am Sep 18 < atjob
    

    或使用管道从标准输入:

    cat atjob | at 6 am 9/18
    

    首先尝试在命令行中使用 at 来安排在不久的将来(例如现在或一分钟后)执行的命令,这样您就可以查看它是否有效,并使用一个非常简单的命令来产生可观察到的东西,例如新的文件。例如,第一个测试作业可以是 'echo hello > /tmp/atfile01',第一个测试作业可以这样提交:

    echo "echo hello > /tmp/atfile01" |现在

    运行之后,检查 /tmp/atfile01 是否存在,如果存在则证明 at 系统是可操作的。

    然后尝试安排工作在 9 月 18 日早上 6 点(如果今天是 9 月 18 日或使用您的时间规格,则从现在开始几天)运行

    echo "echo hello > /tmp/atfile02" | 9 月 18 日早上 6 点

    如果没有产生错误,那么它起作用了,这可以通过运行 atq 来确认,并查看它是否列出了安排为 YYYY-09-18 06:00 的作业,其中 YYYYY 是当前年份或明年如果今年的 9/18 已经过去了。

    现在您知道如何编写和运行 at 作业了,最好使用 atrm 从 at 队列中删除任何测试作业,使用 atq 列出包括其 ID 在内的作业,然后在 ID 上执行 atrm。例如,假设 id 为 2、10 和 17,atrm 命令将是:

    atrm 2 10 17
    

    现在修改您的工作命令以适合您的目的,并使用subprocessshenvoy 从 Python 执行它。使用 suprocess 的示例位于 Calling an external command in Python

    有关 at 的更多信息,您可以通过运行“man at”查看它的手册页,它的 Ubuntu 手册页是 at.1posix.html

    【讨论】:

    • 感谢@Tris Nefzger。所以 python-crontab 不能这样做......使用类似:cron_job.hour.at(24) ?
    • @adhawan:当然,您可以使用 cron 作业设置 at 作业,并且可以使用 cron 作业删除 cron 作业,但最终仍有 cron 作业等待再次执行。但是,我想出了一种方法来做你想做的事——自毁的 cron 工作。我的答案的第二段中对此进行了解释。
    猜你喜欢
    • 2021-03-14
    • 2013-09-02
    • 2011-09-06
    • 1970-01-01
    • 2014-07-17
    • 2013-01-05
    • 2021-09-10
    • 2021-07-22
    • 2015-08-22
    相关资源
    最近更新 更多