手动立即运行一个cron作业

(我已经阅读了如何testing一个新的cron脚本? )

我有一个特定的问题(cron作业似乎不运行,或正常运行),但问题是一般的:我想debugging脚本是cronned。 我知道我可以设置一个* * * * * crontab行,但这不是一个完全令人满意的解决scheme。 我希望能够从命令行运行cron作业,就好像cron正在运行它(相同的用户,相同的环境variables等)。 有没有办法做到这一点? 不得不等待60秒来testing脚本更改是不实际的。

    这是我所做的,似乎在这种情况下工作。 至less,它显示我一个错误,而从命令行运行,因为用户不显示错误。


    第1步 :我把这行暂时放在用户的crontab中:

    * * * * * /usr/bin/env > /home/username/tmp/cron-env 

    然后一旦写入文件就拿出来。

    第2步 :为自己做一个小小的run-as-cron bash脚本,其中包含:

     #!/bin/bash /usr/bin/env -i $(cat /home/username/tmp/cron-env) "$@" 

    那么,作为用户的问题,我能够

     run-as-cron /the/problematic/script --with arguments --and parameters 

    这个解决scheme显然可以扩展到使用sudo或更多的灵活性。

    希望这可以帮助别人。

    我提出了一个基于Pistos的解决scheme,但没有缺陷。

    • 将以下行添加到crontab,例如使用crontab -e

       * * * * * /usr/bin/env > /home/username/cron-env 
    • 创build一个shell脚本,它在cron作业运行的环境中执行一个命令:

       #!/bin/sh . "$1" exec /usr/bin/env -i "$SHELL" -c ". $1; $2" 

    使用:

     run-as-cron <cron-environment> <command> 

    例如

     run-as-cron /home/username/cron-env 'echo $PATH' 

    请注意,如果需要参数,则需要引用第二个参数。 脚本的第一行加载一个POSIX shell作为解释器。 第二行来源于cron环境文件。 这是加载正确的shell所需的,它存储在环境variablesSHELL 。 然后加载一个空的环境(以防止环境variables泄漏到新的shell中),启动用于cronjobs的同一个shell并加载cron环境variables。 最后执行命令。

    由于crontab不做这个工作,你可以操纵它的内容:

     crontab -l | grep -v '^#' | cut -f 6- -d ' ' | while read CMD; do eval $CMD; done 

    它能做什么 :

    • 列出crontab作业
    • 删除注释行
    • 删除crontabconfiguration
    • 然后逐一启动

    默认情况下,我已经看到大多数默认的cron守护进程,现在根本没有办法告诉cron在这里运行。 如果你正在使用anacron,我想可能会在前台运行一个单独的实例。

    如果你的脚本运行不正常,那么你没有考虑到这一点

    • 该脚本作为特定用户运行
    • 克朗有一个有限的环境(这是最明显的performance是一个不同的path)。

    从crontab(5):

    几个环境variables由cron(8)守护进程自动设置。 SHELL设置为/ bin / sh,LOGNAME和HOME是从crontab所有者的/ etc / passwd行设置的。 PATH设置为“/ usr / bin:/ bin”。 HOME,SHELL和PATH可以被crontab中的设置覆盖; LOGNAME是作业运行的用户,可能不会更改。

    一般来说PATH是最大的问题,所以你需要:

    • 在testing过程中,将脚本内的PATH显式设置为/ usr / bin:/ bin。 你可以在bash中用export PATH =“/ usr / bin:/ bin”
    • 在crontab的顶部显式设置你想要的PATH。 例如PATH =“/ usr / bin:/ bin:/ usr / local / bin:/ usr / sbin:/ sbin”

    如果您需要以不带shell的其他用户(例如www-data)运行脚本,请使用sudo:

     sudo -u www-data /path/to/crontab-script.sh 

    在所有这些之前首先要testing的是,脚本实际上是从命令行执行的。 如果你不能从命令行运行它,它显然不能从cron运行。

    那么,用户和你放在crontab项中的用户是一样的(或者你把crontab放在哪个crontab中),所以这是一个不容易的事情。 crontab (5)应该给你设置环境variables的列表,只有less数。

    在像vixie-cron这样的大多数crontabs中,你可以像这样在crontab中放置variables,然后使用/ usr / bin / env来检查它是否工作。 这样,一旦你发现run-as-cron脚本出了什么问题,你就可以使脚本在crontab中工作。

     SHELL=/bin/bash LANG=en FASEL=BLA * * * * * /usr/bin/env > /home/username/cron-env 

    马可的剧本由于某种原因不适合我。 我没有时间去debugging,所以我写了一个Python脚本来完成同样的任务。 这是更长的时间,但是:首先,它适用于我,其次,我觉得更容易理解。 将“/ tmp / cron-env”更改为保存环境的位置。 这里是:

     #!/usr/bin/env python from __future__ import division, print_function import sys import os def main(): if len(sys.argv) != 2 or sys.argv[1] in ('-h', '--help'): print("Usage: {} CMD\n" "Run a command as cron would. Note that CMD must be quoted to be only one argument." .format(sys.argv[0])) sys.exit(1) _me, cmd = sys.argv env = dict(line.strip().split('=', 1) for line in open('/tmp/cron-env')) sh = env['SHELL'] os.execvpe(sh, [sh, '-c', cmd], env) if __name__ == '__main__': main() 

    Marco的解决scheme不适合我,但Noam的Python脚本工作。 Marco的剧本略微修改了一下,使之适合我:

     #!/bin/sh . "$1" exec /usr/bin/env -i "$SHELL" -c "set -a;. $1; $2" 

    添加的set -a在脚本$ 1中定义的导出variables,并使其可用于命令$ 2

    ps Noam的python工作是因为它将环境导出到subprocess。

    我从来没有find一种方法来手动运行cron作业,但是这种写法build议设置与cronjob相同的环境,并手动运行脚本。

    你可以编程的工作开始下一分钟:)

    如果你只是需要立即运行它,只要testing,使用这种格式:

     second, minute, hour, day, * ? * 

    例如,如果你想今天(9/20/2016)在16:30运行。

     0 30 16 20 * ? * 

    确保你以后改变你的cron工作,因为这将在每个月的20号运行。