通常,crontab
脚本不会按计划或按预期执行。有很多原因:
该社区维基旨在汇总crontab
脚本未按预期执行的主要原因。在单独的答案中写下每个原因。
请在每个答案中包含一个原因 - 未执行原因的详细信息 - 并针对该原因进行修复。
请只编写特定于 cron 的问题,例如在 shell 中按预期执行但被 cron 错误执行的命令。
gei*_*rha 583
不同的环境
Cron 将最少的一组环境变量传递给您的作业。要查看差异,请添加这样的虚拟作业:
* * * * * 环境 > /tmp/env.output
等待/tmp/env.output
创建,然后再次删除作业。现在将 的内容/tmp/env.output
与env
常规终端中的run输出进行比较。
这里一个常见的“问题”是PATH
环境变量不同。也许您的 cron 脚本使用了在 中somecommand
找到的命令/opt/someApp/bin
,您已将其添加到PATH
中/etc/environment
?cron 会忽略PATH
该文件,因此somecommand
在使用 cron 运行时,从脚本运行将失败,但在终端中运行时可以工作。值得注意的是,变量 from/etc/environment
将传递给 cron 作业,而不是 cron 专门设置的变量,例如PATH
.
要解决这个问题,只需PATH
在脚本顶部设置您自己的变量即可。例如
* * * * * env > /tmp/env.output
有些人更喜欢只使用所有命令的绝对路径。我建议反对。考虑一下如果您想在不同的系统上运行脚本会发生什么,而在该系统上,命令是在其中/opt/someAppv2.2/bin
。您必须遍历整个脚本,替换为/opt/someApp/bin
,/opt/someAppv2.2/bin
而不仅仅是对脚本的第一行进行小的编辑。
您还可以在 crontab 文件中设置 PATH 变量,该变量将应用于所有 cron 作业。例如
#!/bin/bash
PATH=/opt/someApp/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
# rest of script follows
Run Code Online (Sandbox Code Playgroud)
use*_*124 394
我的首要问题:如果您忘记在crontab
文件末尾添加换行符。换句话说,crontab 文件应该以空行结束。
以下是此问题的手册页中的相关部分(man crontab
然后跳到最后):
Although cron requires that each entry in a crontab end in a newline
character, neither the crontab command nor the cron daemon will detect
this error. Instead, the crontab will appear to load normally. However,
the command will never run. The best choice is to ensure that your
crontab has a blank line at the end.
4th Berkeley Distribution 29 December 1993 CRONTAB(1)
Run Code Online (Sandbox Code Playgroud)
ane*_*hep 166
Cron 守护程序未运行。几个月前我真的搞砸了。
类型:
pgrep cron
Run Code Online (Sandbox Code Playgroud)
如果没有看到数字(即 cron 的主 PID),则 cron 没有运行。sudo /etc/init.d/cron start
可以用来启动cron。
编辑:不是通过 /etc/init.d 调用 init 脚本,而是使用服务实用程序,例如
sudo service cron start
Run Code Online (Sandbox Code Playgroud)
编辑:您也可以在现代 Linux 中使用 systemctl,例如
sudo systemctl start cron
Run Code Online (Sandbox Code Playgroud)
Xiè*_*léi 104
在脚本文件名cron.d/
,cron.daily/
,cron.hourly/
等,不应包含点(.
),否则运行部分将跳过他们。
参见运行部分(8):
If neither the --lsbsysinit option nor the --regex option is given then
the names must consist entirely of upper and lower case letters, dig?
its, underscores, and hyphens.
If the --lsbsysinit option is given, then the names must not end in
.dpkg-old or .dpkg-dist or .dpkg-new or .dpkg-tmp, and must belong to
one or more of the following namespaces: the LANANA-assigned namespace
(^[a-z0-9]+$); the LSB hierarchical and reserved namespaces
(^_?([a-z0-9_.]+-)+[a-z0-9]+$); and the Debian cron script namespace
(^[a-zA-Z0-9_-]+$).
Run Code Online (Sandbox Code Playgroud)
因此,如果您在目录中有 cron 脚本backup.sh
,则最好删除扩展名。analyze-logs.pl
cron.daily/
Ian*_*non 82
在许多环境中,cron 使用 执行命令sh
,而许多人认为它会使用bash
.
针对失败的命令测试或修复此问题的建议:
尝试运行该命令sh
以查看它是否有效:
sh -c "mycommand"
Run Code Online (Sandbox Code Playgroud)将命令包装在 bash 子 shell 中以确保它在 bash 中运行:
bash -c "mybashcommand"
Run Code Online (Sandbox Code Playgroud)通过在 crontab 顶部设置 shell 来告诉 cron 在 bash 中运行所有命令:
SHELL=/bin/bash
Run Code Online (Sandbox Code Playgroud)如果命令是一个脚本,请确保该脚本包含一个shebang:
#!/bin/bash
Run Code Online (Sandbox Code Playgroud)小智 49
我对时区有一些问题。Cron 以全新安装时区运行。解决方案是重新启动cron:
sudo service cron restart
Run Code Online (Sandbox Code Playgroud)
Ada*_*tan 42
脚本应该使用绝对路径:
例如,/bin/grep
应该使用而不是grep
:
# m h dom mon dow command
0 0 * * * /bin/grep ERROR /home/adam/run.log &> /tmp/errors
Run Code Online (Sandbox Code Playgroud)
代替:
# m h dom mon dow command
0 0 * * * grep ERROR /home/adam/run.log &> /tmp/errors
Run Code Online (Sandbox Code Playgroud)
这尤其棘手,因为在从 shell 执行时,相同的命令将起作用。原因是它cron
没有PATH
与用户相同的环境变量。
小智 37
如果您的 crontab 命令中有一个%
符号,cron 会尝试解释它。因此,如果您正在使用任何带有 a 的命令%
(例如日期命令的格式规范),您将需要对其进行转义。
这里还有其他好的问题:http :
//www.pantz.org/software/cron/croninfo.html
jet*_*jet 28
Cron 正在调用一个不可执行的脚本。
通过运行chmod +x /path/to/script
,脚本变得可执行,这应该可以解决这个问题。
小智 27
用户的密码也可能已过期。甚至 root 的密码也会过期。您可以tail -f /var/log/cron.log
并且会看到 cron 因密码过期而失败。您可以通过执行以下操作将密码设置为永不过期:passwd -x -1 <username>
在某些系统(Debian、Ubuntu)中,默认情况下不启用 cron 日志记录。在/etc/rsyslog.conf或/etc/rsyslog.d/50-default.conf 中的行:
# cron.* /var/log/cron.log
Run Code Online (Sandbox Code Playgroud)
应编辑 ( sudo nano /etc/rsyslog.conf
) 取消注释为:
cron.* /var/log/cron.log
Run Code Online (Sandbox Code Playgroud)
之后,您需要通过以下方式重新启动 rsyslog
/etc/init.d/rsyslog restart
Run Code Online (Sandbox Code Playgroud)
或者
service rsyslog restart
Run Code Online (Sandbox Code Playgroud)
来源:在 Debian Linux 中启用 crontab 日志记录
在某些系统 (Ubuntu) 中,默认情况下未启用 cron 的单独日志记录文件,但与 cron 相关的日志出现在 syslog 文件中。一个可以使用
cat /var/log/syslog | grep cron -i
Run Code Online (Sandbox Code Playgroud)
查看与 cron 相关的消息。
小智 20
如果您的 cronjob 调用 GUI 应用程序,您需要告诉他们应该使用什么 DISPLAY。
示例:使用 cron 启动 Firefox。
您的脚本应该包含export DISPLAY=:0
某处。
小智 18
如果 cron 表的权限不安全,它会被拒绝
sudo service cron restart
grep -i cron /var/log/syslog|tail -2
2013-02-05T03:47:49.283841+01:00 ubuntu cron[49906]: (user) INSECURE MODE (mode 0600 expected) (crontabs/user)
Run Code Online (Sandbox Code Playgroud)
问题解决了
# correct permission
sudo chmod 600 /var/spool/cron/crontabs/user
# signal crond to reload the file
sudo touch /var/spool/cron/crontabs
Run Code Online (Sandbox Code Playgroud)
pjm*_*rse 13
脚本是位置敏感的。这与在脚本中始终使用绝对路径有关,但并不完全相同。您的 cron 作业cd
在运行之前可能需要到特定目录,例如 Rails 应用程序上的 rake 任务可能需要在应用程序根目录中,以便 Rake 找到正确的任务,更不用说适当的数据库配置等。
所以一个 crontab 条目
23 3 * * * /usr/bin/rake db:session_purge RAILS_ENV=production
会更好
23 3 * * * cd /var/www/production/current && /usr/bin/rake db:session_purge RAILS_ENV=production
或者,为了让 crontab 条目更简单、更不脆弱:
23 3 * * * /home/<user>/scripts/session-purge.sh
使用以下代码/home/<user>/scripts/session-purge.sh
:
cd /var/www/production/current /usr/bin/rake db:session_purge RAILS_ENV=production
pbr*_*pbr 12
当从一个 crontab 文件移动到另一个时,过去有效的Crontab 规范可能会中断。有时原因是您已将规范从系统 crontab 文件移至用户 crontab 文件,反之亦然。
cron 作业规范格式在用户的 crontab 文件(/var/spool/cron/username 或 /var/spool/cron/crontabs/username)和系统 crontabs(/etc/crontab
以及 中的文件/etc/cron.d
)之间有所不同。
系统 crontab 在要运行的命令之前有一个额外的字段“用户”。
这将导致错误说明诸如george; command not found
何时将命令移出/etc/crontab
或将文件/etc/cron.d
移入用户的 crontab 文件。
相反,/usr/bin/restartxyz is not a valid username
当反向发生时,cron 会传递类似或类似的错误。
Bil*_*hor 12
我看到 cron 在错误陈述的时间表中失败的最常见原因。需要练习将安排在晚上 11:15 的作业指定15 23 * * *
为 * * 11 15 *
或11 15 * * *
。午夜之后工作的星期几也变得混乱 MF 是2-6
在午夜之后,而不是1-5
。具体日期通常是一个问题,因为我们很少使用它们* * 3 1 *
不是 3 月 3 日。如果您不确定,请访问https://crontab.guru/在线检查您的 cron 计划。
如果您在不同平台上使用不受支持的选项(例如2/3
时间规范)也可能导致失败。这是一个非常有用的选项,但并非普遍可用。我也遇到过像1-5
或 之类的列表的问题1,3,5
。
使用不合格的路径也会导致问题。默认路径通常是/bin:/usr/bin
这样,只有标准命令才会运行。这些目录通常没有所需的命令。这也会影响使用非标准命令的脚本。其他环境变量也可能丢失。
完全破坏现有的 crontab 给我带来了问题。我现在从文件副本加载。crontab -l
如果它被破坏,可以从现有的 crontab 中恢复。我将 crontab 的副本保存在 ~/bin 中。它贯穿始终并以行结束# EOF
。这是每天从 crontab 条目重新加载的,例如:
#!/usr/bin/crontab # 重新加载这个 crontab # 54 12 * * * ${HOME}/bin/crontab
上面的 reload 命令依赖于一个可执行的 crontab,带有运行 crontab 的 bang 路径。某些系统需要在命令中运行 crontab 并指定文件。如果目录是网络共享的,那么我经常使用crontab.$(hostname)
作为文件名。这最终将纠正在错误服务器上加载错误 crontab 的情况。
使用该文件提供了 crontab 应该是什么的备份,并允许crontab -e
自动取消临时编辑(我唯一使用的时间)。有可用的标题有助于获得正确的调度参数。当没有经验的用户编辑 crontab 时,我已经添加了它们。
我很少遇到需要用户输入的命令。这些在 crontab 下失败,尽管有些可以使用输入重定向。
小智 11
如果你有这样的命令:
* * * * * /path/to/script >> /tmp/output
Run Code Online (Sandbox Code Playgroud)
并且它不起作用并且您看不到任何输出,这可能并不一定意味着 cron 不起作用。脚本可能会被破坏,输出到stderr而不会传递到 /tmp/output。通过捕获此输出来检查情况并非如此:
* * * * * /path/to/script >> /tmp/output 2>&1
Run Code Online (Sandbox Code Playgroud)
看看这是否有助于您解决问题。
小智 10
cron 脚本正在使用 --verbose 选项调用命令
我的 cron 脚本失败了,因为我在键入脚本时处于自动驾驶状态,并且我包含了 --verbose 选项:
#!/bin/bash
some commands
tar cvfz /my/archive/file.tar.gz /my/shared/directory
come more commands
Run Code Online (Sandbox Code Playgroud)
从 shell 执行时脚本运行良好,但从 crontab 运行时失败,因为从 shell 运行时详细输出会转到 stdout,但从 crontab 运行时无处可去。删除“v”的简单修复:
#!/bin/bash
some commands
tar cfz /my/archive/file.tar.gz /my/shared/directory
some more commands
Run Code Online (Sandbox Code Playgroud)
小智 7
如果您通过 SSH 密钥访问帐户,则可以登录该帐户但不会注意到该帐户的密码已被锁定(例如,由于密码过期或无效的密码尝试)
如果系统正在使用 PAM 并且帐户被锁定,这可能会阻止其 cronjob 运行。(我已经在 Solaris 上测试过了,但没有在 Ubuntu 上测试过)
您可能会在 /var/adm/messages 中找到这样的消息:
10 月 24 日 07:51:00 mybox cron[29024]:[ID 731128 auth.notice] pam_unix_account:cron 试图从本地主机验证锁定帐户 myuser 10 月 24 日 07:52:00 mybox cron[29063]:[ID 731128 auth.notice] pam_unix_account:cron 试图从本地主机验证锁定帐户 myuser 10 月 24 日 07:53:00 mybox cron[29098]:[ID 731128 auth.notice] pam_unix_account:cron 试图从本地主机验证锁定帐户 myuser 10 月 24 日 07:54:00 mybox cron[29527]:[ID 731128 auth.notice] pam_unix_account:cron 试图从本地主机验证锁定帐户 myuser
您需要做的就是运行:
# passwd -u <用户名>
以 root 身份解锁帐户,crontab 应该再次工作。