我尝试设置一个 root 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
并在末尾插入这两行。我希望 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 脚本。这次日志中没有显示任何错误。为了确保这不是脚本的内容,我将脚本缩减为以下 3 行:
#!/bin/bash
LOGFILE=/var/log/tunlr.log
echo $LOGFILE >> $LOGFILE
我仍然无法完成 cron 任务。日志文件中没有任何内容。那么空脚本是否也无法在 cron 中运行?我不明白。我尝试将脚本简化为以下两行:
#!/bin/bash
exit 0
错误日志还是一样。cron 脚本没有通过...
答案1
如果你想将脚本作为普通用户:
crontab -e
并添加以下行:
07,37 * * * * /usr/bin/tunlrupdate.sh
如果你想以以下方式运行脚本根:
sudo crontab -e
并添加相同的行:
07,37 * * * * /usr/bin/tunlrupdate.sh
答案2
好吧,终于找到了可行的解决方案。在系统日志中,我看到了重复且有趣的内容:
CRON[18770]: (root) CMD (root /usr/bin/tunlrupdate.sh)
听起来好像 root 未被识别为 cmd。因为我已经通过使用 使用了 root 的 cron $ sudo /usr/bin/tunlrupdate.sh
。然后我尝试使用原始脚本(纠正日期 UNIX cmd 中的错误:%m 即月份被用于分钟,即 %M)执行以下命令(从 cron 行中删除 root):
$ 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 行中的 root 行是错误的。那是一个错误]。
答案3
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
您必须进行测试,直到所有必要的变量都按照脚本的要求进行定义。
答案4
您可以在脚本中添加此行。这样,在您检查 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