通常,crontab脚本未按计划执行或未按预期执行。造成这种情况的原因有很多:


错误的crontab表示法
权限问题
环境变量

该社区Wiki旨在汇总顶部crontab脚本未按预期执行的原因。将每个原因写在一个单独的答案中。

请在每个答案中包含一个原因-有关为什么不执行的详细信息-并为此原因解决。

请写出仅特定于cron的问题,例如从shell按预期执行但cron错误执行的命令。

评论

您必须关闭crontab -e才能使cron生效。例如,使用vim编辑文件并使用:w编写文件,但是直到我也退出后,作业才添加到cron中。因此,我也要等到:q之后才能看到这份工作。

我认为调试cron的最佳方法是检查syslog并查找问题。

以我为例-该电子邮件将进入我的SPAM文件夹,所以.....在进行数小时调试之前请检查一下:D

停电

请检查此一个askubuntu.com/a/1223213/297387

#1 楼

不同的环境

Cron将一组最小的环境变量传递给您的工作。若要查看区别,请添加一个虚拟作业,如下所示:

* * * * * env > /tmp/env.output


等待创建/tmp/env.output,然后再次删除该作业。现在,将/tmp/env.output的内容与在常规终端中运行的env的输出进行比较。

这里常见的“陷阱”是PATH环境变量不同。也许您的cron脚本使用在somecommand中找到的命令/opt/someApp/bin,您已将它添加到PATH中的/etc/environment中? cron会从该文件中忽略PATH,因此使用cron运行脚本时无法从脚本运行somecommand,但是在终端中运行时可以运行。值得注意的是,/etc/environment中的变量将传递给cron作业,而不是cron专门设置的变量,例如PATH。的脚本。例如,

 PATH 


有些人更喜欢对所有命令使用绝对路径。我建议反对。考虑如果要在另一个系统上运行脚本,并且在该系统上该命令位于#!/bin/bash PATH=/opt/someApp/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin # rest of script follows 中,将会发生什么情况。您必须遍历整个脚本,而不是用/opt/someAppv2.2/bin替换/opt/someApp/bin,而不仅仅是对脚本的第一行进行少量编辑。

还可以在crontab文件中设置PATH变量,将适用于所有cron作业。例如

 /opt/someAppv2.2/bin 


评论


我想我只是喜欢这个,换行符结束了……双重打击。

–WernerCD
2011年6月2日,下午4:22

+1表示env,我完全忘记了该命令,以为PATH在起作用。在我看来,这实际上是完全不同的。

–伊兹卡塔
2012年1月18日15:16

@pbr如果此类目录可写给其他用户,则说明该系统已经受到威胁。

– Geirha
2012年4月9日在8:23

@pbr系统管理员可以不经意地删除根文件系统。您无法防止系统管理员犯傻的错误。如果您安装了不向后兼容的较新版本的解释器,则无论如何我都希望它会损坏。处理该问题的理智方法是将其安装为其他命令。例如。您具有python 2.x版本并安装了python 3,则将其安装为python3,而不是python。至于/ opt / someApp / bin,为什么它实际上没有理智的权限/所有权?任何理智的管理员都将确保对系统文件具有理智的权限/所有权。

– Geirha
2012-04-10 6:36



@pbr看来我们可以永远继续下去,是的。我仍然看不到为什么使用PATH是个坏主意。如果您想以更适合讨论的媒介进行进一步讨论,可以在irc.freenode.net上的#ubuntu和#bash及其他渠道中找到我。

– Geirha
2012年4月11日在16:28

#2 楼

我最要注意的是:如果您忘记在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)


评论


这真是个大热门,为什么这么多年的cron没被解决?

– Capi Etheriel
2011-1-27的3:20



似乎已在Vixie cron中修复:Ubuntu 10.10上的man crontab表示“ cron要求crontab中的每个条目都以换行符结尾。如果crontab中的最后一个条目缺少换行符,则cron将考虑crontab(至少部分)损坏,并拒绝安装它。” (截止日期为2010年4月19日。)

– Marius Gedminas
2011年2月1日在22:58

@barraponto这实际上是新文本编辑器中的错误。 “换行”字符应该是行终止符,因此文本文件中的最后一行应该以在编辑器中未显示的换行符结尾。 Vi和vim正确使用了该字符,并且cron是在新编辑者开始其奇怪行为之前构建的。

–伊兹卡塔
2012年1月18日15:20

如果使用crontab -e编辑crontab,它将在允许保存之前检查文件的语法,包括检查换行符。

–汤姆·哈里森(Tom Harrison Jr)
2014年9月26日在18:26

@ Chan-HoSuh,根据手册页所述:“ cron要求crontab中的每个条目都以换行符结尾。如果crontab中的最后一个条目缺少换行符,则cron会认为crontab(至少部分)已损坏,并拒绝安装它。”编辑时将调用此行为,然后使用-e选项保存crontab,并且独立于编辑器。

–汤姆·哈里森(Tom Harrison Jr)
2014年11月18日下午16:40

#3 楼

Cron守护程序未运行。我真的在几个月前搞砸了。

类型:

pgrep cron 


如果没有数字(例如cron的主要PID),那么cron没有运行。 sudo /etc/init.d/cron start可用于启动cron。

编辑:与其通过/etc/init.d调用init脚本,不如使用服务
实用程序,例如

sudo service cron start


编辑:您也可以在现代Linux中使用systemctl,例如

sudo systemctl start cron


评论


感谢您向我展示pgrep。我一直在做ps -ef | grep foo

–ripper234
2011年3月17日在17:01

您也可以使用pidof cron,它将省略其他也带有单词“ cron”的应用程序的结果,例如crontab。

– Pithikos
2014年3月11日在16:19



奇怪的是,所有这些都没有给我任何东西来显示cron正在运行,但是如果我运行sudo service cron start我就可以开始:作业已经在运行:cron

–科琳
15年4月6日在17:04

服务crond如果centos / RHEL启动

–斯里哈里·卡兰斯(Srihari Karanth)
17年1月18日在10:02

#4 楼

cron.d/cron.daily/cron.hourly/等中的脚本文件名不应包含点(.),否则运行部件将跳过它们。

请参见run-parts(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_-]+$).


因此,如果您在backup.sh目录中有cron脚本analyze-logs.plcron.daily/,则最好删除扩展名。

评论


这是一个功能,而不是错误-它可以防止myscript.backup或myscript.original或myscript.rpm-new之类的东西在myscript旁边运行。

– pbr
2012年4月8日在22:45

@pbr:很有意义。至少如果运行部件--test(或其他虚构的选项(如--debug)会输出跳过的文件(包括原因),这对于调试很有帮助。

– Rabarberski
13年5月30日在8:46



如果这是一项功能,那么它不是一个好方法:(很多人在文件名中使用点号(backup.sh是最常见的一种)。如果要停止执行脚本,最合乎逻辑的方法是从“ cron.d”目录中删除它。

– MatuDuke
2014年5月16日13:59



这是一个很糟糕的功能,实际上是一个错误。如果人们希望确保事情只在预期的情况下运行,通常的做法是要求特定的结尾(例如“ .list”或“ .cron”等)。随意选择点作为“ .bak”或“ .temp”或任何其他内容的可能分隔符,这完全是不可预测的,除非会以可预见的方式使人们感到困惑。诸如“ .sh”和“ .pl”之类的合法结尾已经广泛使用了数十年。但是,很多人使用“ _bak”或“ _temp”或“ -bak”代替点。这是一个糟糕的设计选择。充其量是设计错误。

– Teekin
17年5月10日在20:42



等待,这是否意味着即使将以下命令添加到crontab中,我的shell脚本pull-data.sh也将永远不会执行:/ bin / bash /home/userName/pull-data.sh吗?

– RodrikTheReader
9月25日下午1:21

#5 楼

在许多环境中,cron使用sh执行命令,而许多人则认为它将使用bash

建议针对失败的命令进行测试或修复:



尝试在sh中运行命令以查看其是否有效:

sh -c "mycommand"



将命令包装在bash子外壳中以确保其在其中运行bash:

bash -c "mybashcommand"



通过在crontab顶部设置外壳,告诉cron在bash中运行所有命令:

SHELL=/bin/bash



如果命令是脚本,请确保该脚本包含shebang:

#!/bin/bash




评论


bash建议非常有用,已解决我的cron问题。

– Maxim Galushka
16年2月18日在22:38

这只是给我造成了1小时的麻烦/故障排除。如果您不知道该问题,则更令人困惑的是,如果您通常的shell是bash,则脚本将手动运行就可以了,但是对于cron而言,则不会。谢谢!

–亨迪
16年11月22日在19:42

很久以前,我遇到了一些相关问题:命令源位于bash中,但不位于sh中。在cron / sh中,使用句点:。 envfile,而不是源envfile。

– kungphu
17/12/22在2:24

@Clockwork sh“ mycommand”告诉sh将mycommand作为脚本文件运行。您是说sh -c“ mycommand”吗?无论如何,这个答案似乎是关于使命令专门在bash中运行,那么为什么在这里为sh添加命令呢?

– Olorin
19年2月8日在9:53

@Olorin据我所知,第一点的目的是尝试使用sh运行它,以查看问题是否真正来自cron使用sh而不是bash运行它的事实。再说一次,我对此事知之甚少,所以我可能是错的。

–钟表
19年2月8日在10:12

#6 楼

我在时区有一些问题。 Cron正在使用全新的安装时区运行。解决方案是重新启动cron:

sudo service cron restart


评论


是的,在更改系统时区后,必须重新启动所有关心时间的服务,或者重新启动。我更喜欢重新启动,以确保我抓到了所有东西。

– pbr
2012年4月8日在22:48

噢,看在上帝的份上,为此花了几个小时。 * * * * * touch / tmp / cronworks没有执行任何操作后,尝试重新启动服务,但cronlog中有RELOAD。

–НЛО
2014年10月1日,下午3:57

这解决了它,即使我的时区没有问题

–埃文·德斯塔(Aven Desta)
5月16日16:08

#7 楼

脚本应使用绝对路径:

例如,应使用/bin/grep代替grep

# m h  dom mon dow   command
0 0 *  *  *  /bin/grep ERROR /home/adam/run.log &> /tmp/errors


代替:

# m h  dom mon dow   command
0 0 *  *  *  grep ERROR /home/adam/run.log &> /tmp/errors


这特别棘手,因为从shell执行相同的命令即可。原因是cron与用户没有相同的PATH环境变量。

评论


查看geirha答案,您可以(必须)定义cron的路径

– Capi Etheriel
2011-1-27的3:22

zz您无需定义PATH-使用绝对路径是此处的最佳做法。 “因为可执行文件可能在其他计算机上的其他位置”并不胜过“我希望它完全运行此程序,而不是其他人将其放在原始程序的前面”

– pbr
2012年4月8日在22:55

是的,对我来说就是这样,在cron之外,我可以直接运行命令,在cron里面,它需要完整的/ usr / bin /任何路径

–熵
16年8月14日在10:56

#8 楼

如果您的crontab命令中包含%符号,则cron尝试对其进行解释。因此,如果您正在使用带有%的任何命令(例如date命令的格式规范),则需要对其进行转义。

这里还有其他一些不错的地方:http:// www .pantz.org / software / cron / croninfo.html

评论


这就是导致我的Cron工作在过去一周中失败的原因。最终发现我的Date没有转义字符(对于寻找转义字符的其他任何人都使用反斜杠)。好极了!

–华伦
13-10-14在14:27



另请参阅如何在cron选项卡作业中执行日期?

–Jared Beck
15年4月16日在20:49

#9 楼

Cron正在调用不可执行的脚本。

通过运行chmod +x /path/to/script,脚本将变为可执行文件,这应该可以解决此问题。

评论


这不是cron独有的,并且可以通过尝试从命令行执行/ path / to / script轻松地进行跟踪。

–亚当·马坦(Adam Matan)
2011年1月27日,下午6:33

如果您习惯使用来执行脚本。脚本名或sh脚本名或bash脚本名,那么这将成为特定于cron的问题。

– Eliah Kagan
2011年11月24日23:09

#10 楼

用户的密码也可能已过期。甚至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


应编辑(sudo nano /etc/rsyslog.conf),不作注释:

cron.*                          /var/log/cron.log


之后,您需要通过

/etc/init.d/rsyslog restart




service rsyslog restart 


源:在Debian Linux中启用crontab日志

在某些系统(Ubuntu)中,默认情况下未启用cron的单独日志文件,但在cron相关的日志中syslog文件。可以使用

cat /var/log/syslog | grep cron -i


查看与cron相关的消息。

评论


我有Debian(忙),但没有/etc/init.d/rsyslog,只有inetutils-syslogd和sysklogd。我需要安装某些东西还是只是重新启动两者之一?

– hgoebl
16-10-21在11:41

#11 楼

如果您的cronjob调用GUI应用程序,则需要告诉他们应该使用什么显示。

示例:使用cron启动Firefox。

您的脚本应该在某处包含export DISPLAY=:0

评论


一个游戏出于某种原因需要这个。谢谢

–IljaBek
16-10-2在10:47

* * * * *导出DISPLAY =:0 && <命令>

–LoMaPh
17年7月27日在22:27



#12 楼

不安全的cron表权限

如果cron表的权限不安全,则拒绝该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)


通过

解决了问题/>
# correct permission
sudo chmod 600 /var/spool/cron/crontabs/user
# signal crond to reload the file
sudo touch /var/spool/cron/crontabs


评论


首先,我自己弄清楚了,然后找到了答案!还是非常感谢!就我而言,我已经通过SVN还原了/ var / spool / cron / crontabs中的一些crontab,从而更改了其权限!

– alfonx
13年6月8日在20:40

#13 楼

恐怕权限问题很常见。

请注意,常见的解决方法是使用root的crontab执行所有操作,有时这是一个很糟糕的主意。设置适当的权限肯定是一个很大程度上被忽略的问题。

评论


请注意,如果您将crontab行设置为通过管道将输出传递到尚不存在的文件,并且该文件的目录是cron用户无法访问的目录,则该行将不会执行。

–埃文·多诺万(Evan Donovan)
2015年9月10日下午16:51

#14 楼

脚本对位置敏感。这与在脚本中始终使用绝对路径有关,但并不完全相同。您的Cron作业可能需要先运行到特定目录,然后再运行,例如Rails应用程序上的rake任务可能需要位于应用程序的根目录中,以便Rake找到正确的任务,更不用说适当的数据库配置了。等等。

因此,
的crontab条目
cd

会更好,

23 3 * * * cd /var/www/production/current && /usr/bin/rake db:session_purge RAILS_ENV=production


或者,为了使crontab条目更简单且不那么脆弱:
23 3 * * * /usr/bin/rake db:session_purge RAILS_ENV=production

23 3 * * * /home/<user>/scripts/session-purge.sh中包含以下代码:

cd /var/www/production/current
/usr/bin/rake db:session_purge RAILS_ENV=production


评论


如果从cron调用的脚本是用PHP之类的解释语言编写的,则可能需要在脚本本身中设置工作目录。例如,在PHP中:chdir(dirname(__ FILE__));

–埃文·多诺万(Evan Donovan)
2015年9月10日在16:14



刚接触到这一点:脚本曾经位于我的主目录的根目录中,但是后来我将其移动(并更新了crontab),无法弄清楚为什么它不起作用。事实证明该脚本使用的是相对路径,假设它是相对于脚本的位置,但实际上是相对于我的主目录的根目录的,因为这是cron使用的工作目录,这就是该脚本的原因当它位于我的主目录的根目录中时就可以正常工作(因为脚本的预期工作目录与实际工作恰巧发生了巧合)。

–米歇尔·约翰逊(Micheal Johnson)
16年4月4日在18:36

#15 楼

从过去的Crontab规范在从一个crontab文件移动到另一个文件时可能会中断。有时原因是您已将规范从系统crontab文件移至用户crontab文件,反之亦然。 / cron / username或/ var / spool / cron / crontabs / username)和系统crontab(/etc/crontab/etc/cron.d中的文件)。

系统crontab前面有一个额外的字段'user'命令运行。

当您将命令从george; command not found/etc/crontab中的文件移出到用户的crontab文件中时,这将导致诸如/etc/cron.d之类的错误。相反,当发生相反的情况时,cron将发出类似/usr/bin/restartxyz is not a valid username之类的错误。

#16 楼

如果您有这样的命令:

* * * * * /path/to/script >> /tmp/output


它不起作用并且看不到任何输出,则不一定表示cron不起作用。该脚本可能已损坏,并且输出将传递到stderr,该输出不会传递到/ tmp / output。通过捕获以下输出来检查是否不是这种情况:

* * * * * /path/to/script >> /tmp/output 2>&1


,看看这是否有助于您解决问题。

#17 楼

cron脚本正在调用带有--verbose选项的命令

我遇到了cron脚本失败,因为我在键入脚本时处于自动导航状态,并且包括了--verbose选项:

#!/bin/bash
some commands
tar cvfz /my/archive/file.tar.gz /my/shared/directory
come more commands


从shell执行时,脚本运行良好,但从crontab运行时,脚本失败,因为从shell运行时,详细输出进入stdout,但是从crontab运行时,无输出。轻松修复以删除'v':

#!/bin/bash
some commands
tar cfz /my/archive/file.tar.gz /my/shared/directory
some more commands


评论


为什么这会导致故障?缓冲区问题?

–亚当·马坦(Adam Matan)
2012年5月31日下午6:38

通过cron作业触发的任何输出或错误都将发送到您的邮箱,因此我们永远不要忘记关心这些错误/输出,我们可以将它们重定向到任何文件或/ dev / null

– Nischay
2013年9月27日上午11:32

#18 楼

我见过cron失败的最常见原因是时间表不正确。练习将计划在11:15 pm预定的作业指定为15 23 * * *而不是* * 11 15 *11 15 * * *。午夜后工作的星期几也会变得混乱,M-F是午夜后的2-6,而不是1-5。特定日期通常是个问题,因为我们很少使用它们。* * 3 1 *不是3月3日。如果不确定,请访问https://crontab.guru/在线检查cron计划。

如果在不同平台上使用不支持的选项(例如,时间规格为2/3)工作也会导致失败。这是一个非常有用的选项,但并非通用。我还遇到了与1-51,3,5之类的列表有关的问题。

使用不合格的路径也会引起问题。默认路径通常是/bin:/usr/bin,因此仅标准命令将运行。这些目录通常没有所需的命令。这也会影响使用非标准命令的脚本。其他环境变量也可能丢失。

破坏现有的crontab完全给我带来了问题。我现在从文件副本加载。可以使用crontab -l从现有的crontab中恢复该文件,以防万一。我将crontab的副本保留在〜/ bin中。全文注释并以# EOF行结尾。这是每天从crontab条目重新加载的,例如:

#!/usr/bin/crontab
# Reload this crontab
#
54 12    *   *   *   ${HOME}/bin/crontab


上面的reload命令依赖于具有运行crontab的爆炸路径的可执行crontab。某些系统需要在命令中运行crontab并指定文件。如果目录是网络共享的,那么我经常使用crontab.$(hostname)作为文件名。这最终将纠正在错误的服务器上加载了错误的crontab的情况。

使用该文件可备份crontab的内容,并允许自动撤消临时编辑(仅当我使用crontab -e时)。有可用的标题,可帮助正确设置调度参数。当经验不足的用户正在编辑crontab时,我已经添加了它们。

我很少遇到需要用户输入的命令。这些方法在crontab下失败,尽管某些方法可用于输入重定向。

评论


这涵盖了三个独立的问题。可以将它们分为单独的答案吗?

– Eliah Kagan
2011年11月24日23:07

您能解释一下30 23 * * *转换为11:15 PM吗?

–耶尔顿
2014年1月10日19:23

@JYelton显然是错误的,应该是15 23 * * *。现在已更正。

–梅勒比乌斯
19年6月19日在8:09

时区应在此处添加:我的服务器位于UTC上,与我的实际时区完全不同;这与分钟无关,但是与您上班时间无关。...我只是想了一下,为什么我试图在当前小时中每分钟测试一次的cronjob无法正常工作...

–Fons MA
8月20日的1:34

#19 楼

如果您通过SSH密钥访问帐户,则可以登录该帐户,但不会注意到该帐户的密码已锁定(例如,由于过期或无效的密码尝试)。

如果系统是使用PAM并且帐户已锁定,这可以阻止其cronjob运行。 (我已经在Solaris上进行了测试,但未在Ubuntu上进行过测试)

您可以在/ var / adm / messages中找到类似的消息:

Oct 24 07:51:00 mybox cron[29024]: [ID 731128 auth.notice] pam_unix_account: cron attempting to validate locked account myuser from local host
Oct 24 07:52:00 mybox cron[29063]: [ID 731128 auth.notice] pam_unix_account: cron attempting to validate locked account myuser from local host
Oct 24 07:53:00 mybox cron[29098]: [ID 731128 auth.notice] pam_unix_account: cron attempting to validate locked account myuser from local host
Oct 24 07:54:00 mybox cron[29527]: [ID 731128 auth.notice] pam_unix_account: cron attempting to validate locked account myuser from local host


您需要做的是运行:

# passwd -u <USERNAME>

以root身份解锁帐户,crontab应该可以再次工作。

#20 楼

=== Docker警报===

如果您使用的是docker,

我认为应该补充一点,我无法使cron运行

要在容器内运行cron作业,我使用了超级用户并运行cron -f以及其他过程。

编辑:另一个问题-我也没有使用HOST网络运行容器时,设法使其正常工作。也可以在这里查看此问题:https://github.com/phusion/baseimage-docker/issues/144

评论


stackoverflow.com/questions/37458287/…

–西蒙D
18/12/17在9:53

#21 楼

我正在编写一个安装Shell脚本,该脚本创建另一个脚本以从数据库中清除旧的事务数据。作为任务的一部分,它必须配置每日cron作业以在数据库负载较低时在任意时间运行。

我创建了带有cron计划,用户名和命令的文件mycronjob,并将其复制到/etc/cron.d目录。我的两个陷阱:mycronjob文件必须由root拥有才能运行
我必须将文件的权限设置为644-664无法运行。

权限问题将在/var/log/syslog中出现,类似于以下内容:

Apr 24 18:30:01 ip-11-22-33-44 cron[40980]: (*system*) INSECURE MODE (group/other writable) (/etc/crontab)
Apr 24 18:30:01 ip-11-22-33-44 cron[40980]: (*system*) INSECURE MODE (group/other writable) (/etc/cron.d/user)


第一行引用/etc/crontab文件,第二行引用文件我放在/etc/cront.d下。

#22 楼

以crontab无法理解的方式编写的行。需要正确编写。这是CrontabHowTo。

评论


如何调试?

–亚当·马坦(Adam Matan)
11年1月27日在6:34

查看cron的错误日志是最常见的方法。编辑完文件后,IIRC'crontab -e'也会进行语法解析-但这可能不是通用的。

– pbr
2012年4月8日在22:47

#23 楼

Cron守护程序可能正在运行,但实际上没有运行。尝试重新启动cron:

sudo /etc/init.d/cron restart


评论


我从未在生产中看到过这种情况。这并不意味着它没有发生-只是我在使用UNIX和Linux的30年中没有看到它。 Cron非常健壮。

– pbr
2012年4月8日在22:42



我不确定,但我认为这确实发生在我身上。我尝试了pidof cron,却一无所获。尝试使用Service Utility,并说cron已经在运行。只需运行此命令并再次运行pidof,我就会得到结果。

–科琳
2015年4月6日在17:13

#24 楼

通过“ crontab -e”在一行中使用username参数写入cron。我已经看到了一些用户(或系统管理员)编写自己的Shell脚本并且不了解为什么他们不自动化的示例。 “用户”参数存在于/ etc / crontab中,但不存在用户定义的文件。因此,例如,您的个人文件应为:

# m h dom mon dow command

* * */2  *   *  /some/shell/script


,而/ etc / crontab将是: >
那为什么要选择后者呢?好吧,这取决于您要如何设置权限,这可能会非常令人费解。我已经编写了脚本来为不了解复杂性或不想打扰工作的用户自动执行任务。通过将权限设置为--x------,我可以使脚本可执行,而无需他们能够读取(或不小心更改)脚本。但是,我可能想从一个文件中与其他几个命令一起运行此命令(从而使维护更容易),但要确保为文件输出分配了正确的所有者。这样做(至少在Ubuntu 10.10中)打破了既无法读取文件又无法执行的问题,还打破了前面提到的在/ etc / crontab中放置句点的问题(有趣的是,通过crontab -e时不会引起任何错误) )。

作为示例,我已经看到sudo crontab -e的实例用于运行具有root权限的脚本,并且在shell脚本中具有相应的chown username file_output。马虎,但它的工作原理。恕我直言,更优雅的选择是将其放入带有声明的用户名并具有适当权限的/etc/crontab中,以便file_output移至正确的位置和所有者。

评论


“这样做(至少在Ubuntu 10.10中这样做会打破无法读取文件以及无法执行.....”的意思。)我应该澄清一下:/ etc / crontab(默认情况下)需要读取和执行权限,而您可以运行“ sudo crontab -e”来创建一个cronjob,它会覆盖对“ w”权限的需求以及诸如“ .sh”扩展名的问题。我还没来得及分解cron代码并检查它为何有效,只是我注意到的一个细节。

– Mange
2012年6月12日19:54



#25 楼

建立在Aaron Peart所提到的详细模式的基础上,有时,如果包含的命令的默认行为是在proc启动后向屏幕输出一行或更多行,则不是处于详细模式的脚本将初始化但无法完成。例如,我为我们的Intranet编写了一个备份脚本,该脚本使用curl实用程序,该实用程序将文件下载或上传到远程服务器,并且如果您只能通过HTTP访问该远程文件,则非常方便。使用'curl http://something.com/somefile.xls'导致我编写的脚本挂起并从未完成,因为它会吐出换行符和进度行。我必须使用静默标志(-s)告诉它不输出任何信息,并编写自己的代码来处理文件下载失败的问题。

评论


对于没有静默模式的程序,可以将其输出重定向到/ dev / null。例如:some-command> / dev / null这将仅重定向标准输出,而不重定向错误输出(这通常是您想要的,因为您想知道错误信息)。要重定向错误输出,也可以使用一些命令&> / dev / null。

– Eliah Kagan
2012年6月12日20:22

是的,这是我编写上述脚本时的第一个想法。我忘了为什么我不使用它,可能是某些绕过上述解决方案的非标准行为。我知道在某些命令中默认是详细/交互模式(我正在看你的scp!),这意味着您需要使所说的输出混乱,以使Shell脚本顺利运行。

– Mange
2012年6月13日12:09

#26 楼

尽管您可以在crontable中定义环境变量,但是您不在shell脚本中。因此,类似以下的构造将无法正常工作:

SOME_DIR=/var/log
MY_LOG_FILE=${SOME_LOG}/some_file.log

BIN_DIR=/usr/local/bin
MY_EXE=${BIN_DIR}/some_executable_file

0 10 * * * ${MY_EXE} some_param >> ${MY_LOG_FILE}


这是因为在crontable中未解释变量:所有值都是乱码。如果省略括号,也是一样。
因此您的命令将无法运行,并且日志文件也不会被写入...

相反,您必须定义所有环境直接变量:

SOME_DIR=/var/log
MY_LOG_FILE=/var/log/some_file.log

BIN_DIR=/usr/local/bin
MY_EXE=/usr/local/bin/some_executable_file

0 10 * * * ${MY_EXE} some_param >> ${MY_LOG_FILE}


#27 楼

在cron中运行任务时,stdin将关闭。基于stdin是否可用而行为不同的程序在shell会话和cron中的行为将有所不同。

示例是用于分析Web服务器日志文件的程序goaccess。这在cron中不起作用:

goaccess -a -f /var/log/nginx/access.log > output.html


,而goaccess显示帮助页面而不是创建报告。在shell中,可以使用
goaccess -a -f /var/log/nginx/access.log > output.html < /dev/null
复制该问题。goaccess的修复方法是使其从stdin中读取日志,而不是从文件中读取日志,因此解决方案是将crontab条目更改为

cat /var/log/nginx/access.log | goaccess -a > output.html


#28 楼

记录权限

一个非常简单的crontab不会执行,因为/var/log/帐户无法写入luser

* * * * * /usr/local/bin/teamviewer_check >> /var/log/teamviewer.log 2>&1


解决方案:创建文件以root身份和chmod777

由于先前建议在/etc/rsyslog.d/50-default.conf中启用cron日志记录,导致系统日志条目(No MTA installed, discarding output),然后由于“((CRON))信息(未安装MTA,丢弃输出)”错误在以本地模式安装postfix的syslog中,tail / var / mail / luser,/bin/sh: 1: cannot create /var/log/teamviewer.log: Permission denied

#29 楼

在我的情况下,cron和crontab具有不同的所有者。

不起作用,我有这个:

User@Uva ~ $ ps -ef | grep cron | grep -v grep
User    2940    7284 pty1     19:58:41 /usr/bin/crontab
SYSTEM   11292     636 ?        22:14:15 /usr/sbin/cro 


基本上我必须运行cron-config并正确回答问题。有时需要输入“用户”帐户的Win7用户密码。从我的阅读来看,这似乎是一个潜在的安全问题,但是我是单个家庭网络上的唯一管理员,因此我认为这没问题。

以下是使我前进的命令序列:

User@Uva ~ $ cron-config
The cron daemon can run as a service or as a job. The latter is not recommended.
Cron is already installed as a service under account LocalSystem.
Do you want to remove or reinstall it? (yes/no) yes
OK. The cron service was removed.

Do you want to install the cron daemon as a service? (yes/no) yes
Enter the value of CYGWIN for the daemon: [ ] ntsec

You must decide under what account the cron daemon will run.
If you are the only user on this machine, the daemon can run as yourself.
   This gives access to all network drives but only allows you as user.
To run multiple users, cron must change user context without knowing
  the passwords. There are three methods to do that, as explained in
  http://cygwin.com/cygwin-ug-net/ntsec.html#ntsec-nopasswd1
If all the cron users have executed "passwd -R" (see man passwd),
  which provides access to network drives, or if you are using the
  cyglsa package, then cron should run under the local system account.
Otherwise you need to have or to create a privileged account.
  This script will help you do so.
Do you want the cron daemon to run as yourself? (yes/no) no

Were the passwords of all cron users saved with "passwd -R", or
are you using the cyglsa package ? (yes/no) no

Finding or creating a privileged user.
The following accounts were found: 'cyg_server' .
This script plans to use account cyg_server.
Do you want to use another privileged account name? (yes/no) yes
Enter the other name: User

Reenter: User


Account User already exists. Checking its privileges.
INFO: User is a valid privileged account.
INFO: The cygwin user name for account User is User.

Please enter the password for user 'User':
Reenter:
Running cron_diagnose ...
... no problem found.

Do you want to start the cron daemon as a service now? (yes/no) yes
OK. The cron daemon is now running.

In case of problem, examine the log file for cron,
/var/log/cron.log, and the Windows event log (using /usr/bin/cronevents)
for information about the problem cron is having.

Examine also any cron.log file in the HOME directory
(or the file specified in MAILTO) and cron related files in /tmp.

If you cannot fix the problem, then report it to cygwin@cygwin.com.
Please run the script /usr/bin/cronbug and ATTACH its output
(the file cronbug.txt) to your e-mail.

WARNING: PATH may be set differently under cron than in interactive shells.
         Names such as "find" and "date" may refer to Windows programs.


User@Uva ~ $ ps -ef | grep cron | grep -v grep
    User    2944   11780 ?        03:31:10 /usr/sbin/cron
    User    2940    7284 pty1     19:58:41 /usr/bin/crontab

User@Uva ~ $


评论


尽管有据可查,但它看起来像Cygwin特有的观点。它真的属于Askubuntu吗?

–sxc731
16-2-7在11:14

#30 楼

如果您的用户密码已过期,则Cron作业将无法运行。

这表明,如果您的Cron日志(通常相信Ubuntu上为/var/log/syslog)包含诸如“身份验证令牌不再有效;您需要运行一个新密码”。

您可以通过运行sudo chage -l the_username来检查此问题。

以下是密码过期的示例:

$ sudo chage -l root
Last password change                    : password must be changed
Password expires                    : password must be changed
Password inactive                   : password must be changed
Account expires                     : never
Minimum number of days between password change      : 0
Maximum number of days between password change      : 14600
Number of days of warning before password expires   : 14


解决方法是更改​​密码。例如:

sudo -u root passwd


然后按照说明进行操作,并根据提示指定新密码。

感谢https://serverfault.com/问题/ 449651 /为什么我的crontab无法正常工作,以及如何解决我的问题#comment966708_544905,以便在此处向我指出正确的方向。就我而言,就像该评论者一样,它是DigitalOcean框的根用户。