测试每周一次的 cron 作业
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4984725/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Test a weekly cron job
提问by dynamic
I have a #!/bin/bash
file in cron.week directory.
我#!/bin/bash
在 cron.week 目录中有一个文件。
Is there a way to test if it works? Can't wait 1 week
有没有办法测试它是否有效?等不及了 1 周
I am on Debian 6 with root
我在 Debian 6 上使用 root
采纳答案by NNRooth
Just do what cron does, run the following as root
:
只需执行 cron 的操作,运行以下命令root
:
run-parts -v /etc/cron.weekly
... or the next one if you receive the "Not a directory: -v" error:
...或下一个,如果您收到“不是目录:-v”错误:
run-parts /etc/cron.weekly -v
Option -v
prints the script names before they are run.
选项-v
在运行之前打印脚本名称。
回答by Jeremiah Willcock
What about putting it into cron.hourly
, waiting until the next run of hourly cron jobs, then removing it? That would run it once within an hour, and in the cron environment. You can also run ./your_script
, but that won't have the same environment as under cron.
将它放入cron.hourly
,等待下一次每小时运行的 cron 作业,然后将其删除怎么样?这将在一小时内在 cron 环境中运行一次。您也可以运行./your_script
,但它的环境与 cron 下的环境不同。
回答by dave fernholz
I'd use a lock file and then set the cron job to run every minute. (use crontab -e and * * * * * /path/to/job) That way you can just keep editing the files and each minute they'll be tested out. Additionally, you can stop the cronjob by just touching the lock file.
我会使用一个锁定文件,然后将 cron 作业设置为每分钟运行一次。(使用 crontab -e 和 * * * * * /path/to/job)这样你就可以继续编辑文件,每分钟它们都会被测试出来。此外,您只需触摸锁定文件即可停止 cronjob。
#!/bin/sh
if [ -e /tmp/cronlock ]
then
echo "cronjob locked"
exit 1
fi
touch /tmp/cronlock
<...do your regular cron here ....>
rm -f /tmp/cronlock
回答by Low Kian Seong
Aside from that you can also use:
除此之外,您还可以使用:
http://pypi.python.org/pypi/cronwrap
http://pypi.python.org/pypi/cronwrap
to wrap up your cron to send you an email upon success or failure.
结束您的 cron 以在成功或失败时向您发送电子邮件。
回答by Stabledog
A wee bit beyond the scope of your question... but here's what I do.
有点超出了您的问题范围……但这就是我所做的。
The "how do I test a cron job?" question is closely connected to "how do I test scripts that run in non-interactive contexts launched by other programs?" In cron, the trigger is some time condition, but lots of other *nix facilities launch scripts or script fragments in non-interactive ways, and often the conditions in which those scripts run contain something unexpected and cause breakage until the bugs are sorted out. (See also: https://stackoverflow.com/a/17805088/237059)
“我如何测试 cron 作业?” 问题与“如何测试在其他程序启动的非交互式上下文中运行的脚本”密切相关?在 cron 中,触发器是一些时间条件,但许多其他 *nix 工具以非交互方式启动脚本或脚本片段,并且这些脚本运行的条件通常包含一些意外的东西并导致破坏,直到错误被解决。 (另见:https: //stackoverflow.com/a/17805088/237059)
A general approach to this problem is helpful to have.
解决这个问题的一般方法是有帮助的。
One of my favorite techniques is to use a script I wrote called 'crontest'. It launches the target command inside a GNU screen session from within cron, so that you can attach with a separate terminal to see what's going on, interact with the script, even use a debugger.
我最喜欢的技术之一是使用我编写的名为“ crontest”的脚本。它从 cron 内的 GNU 屏幕会话中启动目标命令,以便您可以连接一个单独的终端来查看发生了什么,与脚本交互,甚至使用调试器。
To set this up, you would use "all stars" in your crontab entry, and specify crontest as the first command on the command line, e.g.:
要进行设置,您可以在 crontab 条目中使用“all star”,并将 crontest 指定为命令行上的第一个命令,例如:
* * * * * crontest /command/to/be/tested --param1 --param2
So now cron will run your command every minute, but crontest will ensure that only one instance runs at a time. If the command takes time to run, you can do a "screen -x" to attach and watch it run. If the command is a script, you can put a "read" command at the top to make it stop and wait for the screen attachment to complete (hit enter after attaching)
所以现在 cron 会每分钟运行你的命令,但 crontest 将确保一次只运行一个实例。如果命令需要时间运行,您可以执行“screen -x”来附加并观察它运行。如果命令是脚本,你可以在顶部放一个“读取”命令让它停止并等待屏幕附件完成(附加后按回车)
If your command is a bash script, you can do this instead:
如果你的命令是一个 bash 脚本,你可以这样做:
* * * * * crontest --bashdb /command/to/be/tested --param1 --param2
Now, if you attach with "screen -x", you'll be facing an interactive bashdb session, and you can step through the code, examine variables, etc.
现在,如果您使用“screen -x”附加,您将面临交互式 bashdb 会话,您可以单步执行代码、检查变量等。
#!/bin/bash
# crontest
# See https://github.com/Stabledog/crontest for canonical source.
# Test wrapper for cron tasks. The suggested use is:
#
# 1. When adding your cron job, use all 5 stars to make it run every minute
# 2. Wrap the command in crontest
#
#
# Example:
#
# $ crontab -e
# * * * * * /usr/local/bin/crontest $HOME/bin/my-new-script --myparams
#
# Now, cron will run your job every minute, but crontest will only allow one
# instance to run at a time.
#
# crontest always wraps the command in "screen -d -m" if possible, so you can
# use "screen -x" to attach and interact with the job.
#
# If --bashdb is used, the command line will be passed to bashdb. Thus you
# can attach with "screen -x" and debug the remaining command in context.
#
# NOTES:
# - crontest can be used in other contexts, it doesn't have to be a cron job.
# Any place where commands are invoked without an interactive terminal and
# may need to be debugged.
#
# - crontest writes its own stuff to /tmp/crontest.log
#
# - If GNU screen isn't available, neither is --bashdb
#
crontestLog=/tmp/crontest.log
lockfile=$(if [[ -d /var/lock ]]; then echo /var/lock/crontest.lock; else echo /tmp/crontest.lock; fi )
useBashdb=false
useScreen=$( if which screen &>/dev/null; then echo true; else echo false; fi )
innerArgs="$@"
screenBin=$(which screen 2>/dev/null)
function errExit {
echo "[-err-] $@" | tee -a $crontestLog >&2
}
function log {
echo "[-stat-] $@" >> $crontestLog
}
function parseArgs {
while [[ ! -z ]]; do
case in
--bashdb)
if ! $useScreen; then
errExit "--bashdb invalid in crontest because GNU screen not installed"
fi
if ! which bashdb &>/dev/null; then
errExit "--bashdb invalid in crontest: no bashdb on the PATH"
fi
useBashdb=true
;;
--)
shift
innerArgs="$@"
return 0
;;
*)
innerArgs="$@"
return 0
;;
esac
shift
done
}
if [[ -z $sourceMe ]]; then
# Lock the lockfile (no, we do not wish to follow the standard
# advice of wrapping this in a subshell!)
exec 9>$lockfile
flock -n 9 || exit 1
# Zap any old log data:
[[ -f $crontestLog ]] && rm -f $crontestLog
parseArgs "$@"
log "crontest starting at $(date)"
log "Raw command line: $@"
log "Inner args: $@"
log "screenBin: $screenBin"
log "useBashdb: $( if $useBashdb; then echo YES; else echo no; fi )"
log "useScreen: $( if $useScreen; then echo YES; else echo no; fi )"
# Were building a command line.
cmdline=""
# If screen is available, put the task inside a pseudo-terminal
# owned by screen. That allows the developer to do a "screen -x" to
# interact with the running command:
if $useScreen; then
cmdline="$screenBin -D -m "
fi
# If bashdb is installed and --bashdb is specified on the command line,
# pass the command to bashdb. This allows the developer to do a "screen -x" to
# interactively debug a bash shell script:
if $useBashdb; then
cmdline="$cmdline $(which bashdb) "
fi
# Finally, append the target command and params:
cmdline="$cmdline $innerArgs"
log "cmdline: $cmdline"
# And run the whole schlock:
$cmdline
res=$?
log "Command result: $res"
echo "[-result-] $(if [[ $res -eq 0 ]]; then echo ok; else echo fail; fi)" >> $crontestLog
# Release the lock:
9<&-
fi
回答by Dorlack
I normally test by running the job i created like this:
我通常通过运行我创建的作业来进行测试:
It is easier to use two terminals to do this.
使用两个终端来做到这一点更容易。
run job:
运行作业:
#./jobname.sh
go to:
去:
#/var/log and run
run the following:
运行以下命令:
#tailf /var/log/cron
This allows me to see the cron logs update in real time. You can also review the log after you run it, I prefer watching in real time.
这使我可以实时查看 cron 日志更新。运行后也可以查看日志,我更喜欢实时查看。
Here is an example of a simple cron job. Running a yum update...
这是一个简单的 cron 作业的示例。运行 yum 更新...
#!/bin/bash
YUM=/usr/bin/yum
$YUM -y -R 120 -d 0 -e 0 update yum
$YUM -y -R 10 -e 0 -d 0 update
Here is the breakdown:
这是细分:
First command will update yum itself and next will apply system updates.
第一个命令将更新 yum 本身,接下来将应用系统更新。
-R 120 : Sets the maximum amount of time yum will wait before performing a command
-R 120 : 设置 yum 在执行命令之前等待的最长时间
-e 0 : Sets the error level to 0 (range 0 - 10). 0 means print only critical errors about which you must be told.
-e 0 :将错误级别设置为 0(范围 0 - 10)。0 表示仅打印必须告知您的严重错误。
-d 0 : Sets the debugging level to 0 - turns up or down the amount of things that are printed. (range: 0 - 10).
-d 0 :将调试级别设置为 0 - 增加或减少打印内容的数量。(范围:0 - 10)。
-y : Assume yes; assume that the answer to any question which would be asked is yes
-y :假设是;假设任何问题的答案都是肯定的
After I built the cron job I ran the below command to make my job executable.
构建 cron 作业后,我运行了以下命令以使我的作业可执行。
#chmod +x /etc/cron.daily/jobname.sh
Hope this helps, Dorlack
希望这会有所帮助,多拉克
回答by Automatico
After messing about with some stuff in cron which wasn't instantly compatible I found that the following approach was nice for debugging:
在弄乱了 cron 中的一些不能立即兼容的东西之后,我发现以下方法非常适合调试:
crontab -e
* * * * * /path/to/prog var1 var2 &>>/tmp/cron_debug_log.log
This will run the task once a minute and you can simply look in the /tmp/cron_debug_log.log
file to figure out what is going on.
这将每分钟运行一次任务,您只需查看/tmp/cron_debug_log.log
文件即可了解发生了什么。
It is not exactly the "fire job" you might be looking for, but this helped me a lot when debugging a script that didn't work in cron at first.
这并不完全是您可能正在寻找的“解雇工作”,但是在调试最初在 cron 中不起作用的脚本时,这对我有很大帮助。
回答by n611x007
回答by Ben C
None of these answers fit my specific situation, which was that I wanted to run one specific cron job, just once, and run it immediately.
这些答案都不适合我的具体情况,即我想只运行一次特定的 cron 作业,然后立即运行它。
I'm on a Ubuntu server, and I use cPanel to setup my cron jobs.
我在 Ubuntu 服务器上,我使用 cPanel 来设置我的 cron 作业。
I simply wrote down my current settings, and then edited them to be one minute from now. When I fixed another bug, I just edited it again to one minute from now. And when I was all done, I just reset the settings back to how they were before.
我简单地写下我当前的设置,然后将它们编辑为一分钟后。当我修复另一个错误时,我只是从现在起重新编辑它到一分钟。当我全部完成后,我只是将设置重置为之前的状态。
Example: It's 4:34pm right now, so I put 35 16 * * *, for it to run at 16:35.
示例:现在是下午 4:34,所以我输入 35 16 * * *,让它在 16:35 运行。
It worked like a charm, and the most I ever had to wait was a little less than one minute.
它就像一种魅力,我最需要等待的时间不到一分钟。
I thought this was a better option than some of the other answers because I didn't want to run all of my weekly crons, and I didn't want the job to run every minute. It takes me a few minutes to fix whatever the issues were before I'm ready to test it again. Hopefully this helps someone.
我认为这是比其他一些答案更好的选择,因为我不想运行所有每周的 cron,而且我不想每分钟都运行一次。在我准备再次测试之前,我需要几分钟来解决问题。希望这有助于某人。
回答by Abhilash
The solution I am using is as follows:
我使用的解决方案如下:
- Edit crontab(use command :crontab -e) to run the job as frequently as needed (every 1 minute or 5 minutes)
- Modify the shell script which should be executed using cron to prints the output into some file (e.g: echo "Working fine" >>
output.txt) - Check the output.txt file using the command : tail -f output.txt, which will print the latest additions into this file, and thus you can track the execution of the script
- 编辑 crontab(使用命令 :crontab -e)以根据需要频繁运行作业(每 1 分钟或 5 分钟)
- 修改应该使用 cron 执行的 shell 脚本以将输出打印到某个文件中(例如:echo "Working fine" >>
output.txt) - 使用命令查看 output.txt 文件:tail -f output.txt,该命令会将最新添加的内容打印到该文件中,从而可以跟踪脚本的执行情况