(我已经阅读了如何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
它能做什么 :
默认情况下,我已经看到大多数默认的cron守护进程,现在根本没有办法告诉cron在这里运行。 如果你正在使用anacron,我想可能会在前台运行一个单独的实例。
如果你的脚本运行不正常,那么你没有考虑到这一点
从crontab(5):
几个环境variables由cron(8)守护进程自动设置。 SHELL设置为/ bin / sh,LOGNAME和HOME是从crontab所有者的/ etc / passwd行设置的。 PATH设置为“/ usr / bin:/ bin”。 HOME,SHELL和PATH可以被crontab中的设置覆盖; LOGNAME是作业运行的用户,可能不会更改。
一般来说PATH是最大的问题,所以你需要:
如果您需要以不带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号运行。