如何正确设置根Cron作业


35

我试图设置一个根cron作业,以root身份运行Bash脚本,并在每月的每个小时,每个月的每月7,37分钟运行。该脚本位于/usr/bin并命名为tunlrupdate.sh。它更新Tunlr的DNS。

$ ls -l /usr/bin/tunlrupdate.sh 
-rwxr-xr-x 1 root root 2133 Sep 24 15:42 /usr/bin/tunlrupdate.sh

此Bash脚本可在此处获得

调用脚本时,它将在以下位置的日志中记录正在发生的事情 /var/log/tunlr.log

要添加此root cron作业,我对root的crontab使用了标准

sudo crontab -e

并在最后插入这2行。我希望cron以root身份运行脚本。

# check for updated Tunlr DNS every 30 minutes at the hour + 7 mn and hour + 37 mn
07,37 * * * * root /usr/bin/tunlrupdate.sh

稍后的命令sudo crontab -l确认已插入cron作业。

我确实重新启动了Ubuntu,并且正在检查日志文件中cron作业是否正确启动。但是,日志文件中没有任何内容,这/var/log/tunlr.log意味着该作业从未成功启动。

我确实检查了是否从命令行运行脚本

sudo /usr/bin/tunlrupdate.sh

然后相应地更新日志文件。

为什么此Cron作业在我的系统中未按计划运行?

更新1:到目前为止,所有建议的解决方案均无效。感谢Olli提供的CLI列出系统日志sudo grep CRON /var/log/syslog。但是我确实遇到了CRON错误

CRON[13092]: (root) CMD (  [ -x /usr/lib/php5/maxlifetime ] && [ -d /var/lib/php5 ]
&& find /var/lib/php5/ -depth -mindepth 1 -maxdepth 1 -type f -cmin +$(/usr/lib/php
/maxlifetime) ! -execdir fuser -s {} 2>/dev/null \; -delete)

使用建议的PATH =插入和使用根目录的绝对路径来执行脚本中的函数,或者此处未使用此建议的解决方案。我仍然收到此错误。

经过一番搜索我准确定位文件中的错误/usr/lib/php5/maxlifetime的解释在这里Change #!/bin/sh -e --> #!/bin/sh -x

然后在我的系统中列出CRON错误日志

sudo grep CRON /var/log/syslog
Feb 11 18:07:01 Marius-PC CRON[14067]: (root) CMD (root /usr/bin/tunlrupdate.sh)
Feb 11 18:07:01 Marius-PC CRON[14066]: (root) MAIL (mailed 1 byte of output; but got
status 0x00ff, #012)

我仍然没有执行bash脚本。这次没有错误显示在日志中。为了确保这不是脚本的内容,我将脚本缩减为以下三行:

#!/bin/bash
LOGFILE=/var/log/tunlr.log
echo $LOGFILE >> $LOGFILE

我仍然没有完成Cron工作。日志文件中未写入任何内容。因此,即使是一个空脚本也不会在cron中运行?我不明白 我知道尝试将脚本简化为以下两行:

#!/bin/bash
exit 0

并且仍然是相同的错误日志。cron脚本无法通过...


如果要使其成为“ root” cronjob,则必须是root,然后键入crontab -e。另外,您只需要先以root用户登录(控制台类型为“ su root”),然后再登录crontab -e(在这种情况下不需要sudo)。
Wolfgang'2

好。我看不出您的答案的重点吗?键入$ sudo crontab -e完成了$ sudo crontab -l所报告的工作,即描述新工作的行已添加到根的cron中。就其本身而言,该作业在用户cron中不存在,例如$ crontab -l不显示在此处添加了任何cron作业。
2014年

@WolfgangVogl他使用了“ sudo”,它可以按预期工作。
亚历克西斯·威尔克

Answers:


68

如果要以普通用户身份运行脚本:

crontab -e

并添加以下行:

07,37 * * * * /usr/bin/tunlrupdate.sh

如果要以root用户身份运行脚本:

sudo crontab -e

并添加同一行:

07,37 * * * * /usr/bin/tunlrupdate.sh

@NineCattoRules如果不删除输出,您会看到什么?
安杰洛·福克斯

@AngeloFuchs旧评论...肯定是我以root用户(sudo crontab -e而不是crontab -e)尝试了该命令。还是有其他办法,无论如何都有效
NineCattoRules'5

10

好了,最后是可行的解决方案。在系统日志中,我看到了重复的和有趣的:

CRON[18770]: (root) CMD (root /usr/bin/tunlrupdate.sh)

听起来像root无法识别为cmd。因为我已经使用来使用根的cron $ sudo /usr/bin/tunlrupdate.sh。然后,我尝试使用原始脚本(针对UNIX cmd的日期进行了更正:%m表示错误,%m表示一个月,%m表示分钟),以下内容(从cron行中删除了根):

$ sudo crontab -e
# check for updated Tunlr DNS every 30 minutes at the hour + 7 mn and hour + 37 mn
07,37 * * * * /usr/bin/tunlrupdate.sh

事实证明这是最终的解决方案。[尽管我发现许多文献都指出错误的行,其根在cron行中。那是个错误]。


好点的奥利。我同意你的这个观点。作为参考,用户crontab存储在/ var / spool / cron / crontabs / user-name中,或者存储在根目录/ var / spool / cron / crontabs / root中。请参阅此页面askubuntu.com/questions/216692/where-is-the-user-crontab-stored包含的文件夹已经存在并提供用户名。
安东尼奥

嗯,您不需要该信息,因为您只应使用crontab命令编辑crontab文件(除外下的crontab文件/etc)。
Olli 2014年

1
@Antonio带有用户名字段的分数仅用于/etc/crontab(系统级crontab)。使用sudo crontab -e您正在使用root的crontab,通常可在/var/spool/cron/crontabs
Matijs

2

cron的一个“问题”是缺少环境变量(出于明显的安全原因)。您可能缺少PATH和HOME。您可以直接在脚本中或在crontab文件中定义它们。

# check for updated Tunlr DNS every 30 minutes at the hour + 7 mn and hour + 37 mn
PATH=/usr/bin
07,37 * * * * root /usr/bin/tunlrupdate.sh

您必须进行测试,直到按照脚本的要求定义了所有必需的变量。


1
这是这里唯一对我有用的答案。我从/etc/crontab文件中复制了SHELL和PATH语句,并将它们粘贴到中sudo crontab -e,命令以root身份运行而没有问题。谢谢!
Terrance

0

Cron错误消息通常-默认情况下-通过电子邮件发送。你可以查看是否有电子邮件与根sudo mail,或只是检查内容/var/mail/root,如sudo less /var/mail/root


如果电子邮件没有帮助,请另外检查/var/log/syslog

sudo grep CRON /var/log/syslog

正如Alexis Wilke所说,cron设置环境变量的机制不同。

您的脚本需要

PATH=/sbin:/bin:/usr/bin

到crontab。HOME应该没有必要。您应该在脚本中使用绝对路径,例如/bin/date而不是date。您可以使用来找到每个命令的正确路径 which command_name,例如

$ which date
/bin/date

在/ var / log / syslog中运行建议的grep CRON,我得到了愚蠢的2月11日14:37:01 Marius-PC CRON [7826]:(root)CMD(root /usr/bin/tunlrupdate.sh)2月11日14: 37:01 Marius-PC CRON [7825] :(根)MAIL(已发送1字节的邮件;但状态为0x00ff,#012)2月11日14:39:01 Marius-PC CRON [7849] :(根)CMD( [-x / usr / lib / php5 / maxlifetime] && [-d / var / lib / php5] &&查找/ var / lib / php5 / -depth -mindepth 1 -maxdepth 1 -type f -cmin + $(/ usr / lib / php5 / maxlifetime)!-execdir fuser -s {} 2> / dev / null \; -delete)如果我在cron中为PATH添加了一些定义,这些不会影响我的系统$ PATH吗?
2014年

该输出表示它尝试通过电子邮件发送邮件,但失败了。也就是说,您不会收到该错误消息/var/mail/root。您可以解决此问题,也可以尝试PATH=...
Olli 2014年

@Antonio,或者,使用此修补程序版本
Olli

谢谢。我知道我没有配置系统电子邮件,并且知道没有通过。我已经修改了脚本,以对任何调用的函数使用绝对路径。最后一件事是我先前的问题,crontab中的PATH定义不会弄乱我的系统$ PATH变量吗?
2014年

1
同时,我正忙于纠正原始脚本中日期格式的错误。它使用的是%m(这是一个月的非分钟),而不是%M ...
2014年

0

您可以在脚本中添加此行。因此,在检查了cron日志并批准了作业已执行后,您可以获得与crontabs相同的$ PATH。

/bin/echo $PATH > /root/path.txt

诊断cron脚本中的问题最好的办法就是在脚本中使用env命令获取SO的所有环境变量。因此,只需将此行添加到脚本中即可。然后您可以分析输出allEvnVars.txt

/usr/bin/env > /root/allEvnVars.txt

另一个技巧是将脚本的输出定向到某个位置。添加/root/log.log。这样,脚本的所有输出都将保留在/root/log.log

07,37 * * * * root /usr/bin/tunlrupdate.sh  > /root/log.log

您还可以安排脚本在每分钟运行一次,以方便测试和检查。

*/1 * * * * root /usr/bin/tunlrupdate.sh  > /root/log.log
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.