为什么crontab脚本不起作用?


525

通常,crontab脚本未按计划执行或未按预期执行。原因有很多:

  1. 错误的crontab表示法
  2. 权限问题
  3. 环境变量

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

请为每个答案提供一个原因-未执行原因的详细信息-并出于该原因进行修复。

请仅编写特定于cron的问题,例如,命令会在shell中按预期执行,但cron错误地执行。


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

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

就我而言-电子邮件将进入我的SPAM文件夹,所以.....在进行调试之前要检查一下:D
almaruf

电力中断
约瑟夫·克利穆克

Answers:


501

不同的环境

Cron将最少的环境变量集传递给您的工作。要查看差异,请添加一个虚拟作业,如下所示:

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

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

这里常见的“陷阱”是PATH环境变量不同。也许你的cron脚本使用命令somecommand中发现/opt/someApp/bin,你已经加入PATH/etc/environment?cron会PATH从该文件中忽略,因此somecommand使用cron运行时从脚本运行将失败,但是在终端中运行时可以运行。值得注意的是,from的变量/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/opt/someAppv2.2/bin而不仅仅是在脚本的第一行进行少量编辑。

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

PATH=/opt/someApp/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

15 1 * * * backupscript --incremental /home /root

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

6
为+1 env,我完全忘记了该命令,并认为PATH在起作用。在我看来,这实际上是完全不同的。
伊兹卡塔(Izkata)2012年

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

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

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

336

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

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

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

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

6
如果使用crontab进行编辑crontab -e,它将在允许保存之前检查文件的语法,包括检查换行符。
汤姆·哈里森(Tom Harrison)

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

139

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

类型:

pgrep cron 

如果看不到数字,则说明cron没有运行。sudo /etc/init.d/cron start可以用来启动cron。

编辑:而不是通过/etc/init.d调用初始化脚本,而是使用服务实用程序,例如

sudo service cron start

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

sudo systemctl start cron

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

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

很奇怪,所有这些都没有给我任何东西来显示cron正在运行,但是如果我运行,sudo service cron start我会得到start: Job is already running: cron
Colleen 2015年

1
service crond start如果其centos / RHEL
Srihari Karanth'1

91

该脚本档案名称中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_-]+$).

所以,如果你有一个cron脚本backup.shanalyze-logs.plcron.daily/目录中,你最好删除的扩展名。


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

@pbr:很有意义。至少它本来是用来辅助调试如果run-parts --test(或像另一个假想的选项--debug将输出它跳过其中的原因的文件。
Rabarberski

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

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

68

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

建议针对失败的命令进行测试或解决:

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

    sh -c "mycommand"
    
  • 将命令包装在bash子外壳中,以确保它可以在bash中运行:

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

    SHELL=/bin/bash
    
  • 如果命令是脚本,请确保该脚本包含shebang:

    #!/bin/bash
    

bash建议非常有用,已解决我的cron问题。
马克西姆Galushka

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

很久以前,我遇到了一些相关问题:该命令source以bash而不是sh开头。在cron / sh中,使用句点:. envfile而不是source envfile
kungphu

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

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

39

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

sudo service cron restart

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

噢,看在上帝的份上,为此花了几个小时。尝试执行服务重启后* * * * * touch /tmp/cronworks什么也没做,但RELOAD在cronlog中仍然存在。
2014年

36

脚本应使用绝对路径:

例如,/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与用户相同的环境变量。


3
看到geirha的答案,您可以(必须)定义cron的路径
Capi Etheriel 2011年

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

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

32

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

这和其他好的陷阱在这里:http :
//www.pantz.org/software/cron/croninfo.html


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


25

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

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


5
这不是唯一的cron,并且只需尝试/path/to/script从命令行执行就可以轻松跟踪。
亚当·马坦

4
如果您习惯使用. scriptnamesh scriptname或执行脚本bash scriptname,那么这将成为一个cron特定的问题。
伊莱亚·卡根

24

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

之后,您需要通过以下方式重新启动rsyslog

/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

18

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

示例:使用cron启动Firefox。

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


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

* * * * * export DISPLAY=:0 && <command>
LoMaPh

15

恐怕许可问题很普遍。

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


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

14

不安全的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

12

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

因此,

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 =生产

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

刚被抓住了:脚本曾经位于我的主目录的根目录下,但是后来我将其移动(并更新了crontab),无法弄清楚为什么它不起作用。事实证明脚本使用的是相对路径,假设它是相对于脚本的位置,但实际上是相对于我的主目录的根目录的,因为那是cron使用的工作目录,这就是脚本的原因当它位于我的主目录的根目录中时就可以工作了(因为脚本的预期工作目录与实际工作恰巧发生了巧合)。
米歇尔·约翰逊

11

从过去的 Crontab规范从一个crontab文件移动到另一个文件时可能会中断。有时原因是您已将规范从系统crontab文件移至用户crontab文件,反之亦然。

用户的crontab文件(/ var / spool / cron /用户名或/ var / spool / cron / crontabs /用户名)与系统crontabs(/etc/crontab以及中的文件/etc/cron.d)之间的cron作业规范格式不同。

系统crontab在命令运行之前有一个额外的字段“用户”。

这将导致错误,说明george; command not found您将命令移出/etc/crontab/etc/cron.d移入用户的crontab文件时的情况。

相反,/usr/bin/restartxyz is not a valid username当发生相反的情况时,cron将传递类似或类似的错误。


10

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

5
为什么这会导致故障?缓冲区问题?
亚当·马坦

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

10

我见过cron失败的最常见原因是时间表不正确。指定一个计划在11:15 pm的作业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 crontab -l对其进行破坏来恢复它。我将crontab的副本保留在〜/ bin中。全文注释,以该行结尾# EOF。这是每天从crontab条目中重新加载的,例如:

#!/ usr / bin / crontab
#重新加载此crontab
#
54 12 * * * $ {HOME} / bin / crontab

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

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

我很少遇到需要用户输入的命令。尽管有些将与输入重定向一起使用,但这些命令在crontab下失败。


3
这涵盖了三个独立的问题。可以将它们分为单独的答案吗?
伊利亚·卡根

9
您能解释一下如何30 23 * * * 翻译成晚上11:15吗?
JYelton 2014年

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

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应该可以再次使用。


7

如果您有这样的命令:

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

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

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

看看这是否可以帮助您解决问题。



3

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

mycronjob使用cron计划,用户名和命令创建了一个文件,并将其复制到/etc/cron.d目录中。我的两个陷阱:

  1. mycronjob 文件必须由root拥有才能运行
  2. 我必须将文件的权限设置为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


2

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


1
如何调试?
亚当·马坦

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

2

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

sudo /etc/init.d/cron restart

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

1
我不确定,但我认为这确实发生在我身上。我尝试了pidofcron,却一无所获。尝试使用service实用程序,它说cron已经在运行。只需运行此命令,然后pidof再次运行,我就会得到结果。
科琳2015年

2

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

# m h dom mon dow command

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

而/ etc / crontab将是:

# m h dom mon dow user   command

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

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

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


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

2

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


1
对于没有静默模式的程序,可以将其输出重定向到/dev/null。例如:some-command > /dev/null这将仅重定向标准输出,而不重定向错误输出(这通常是您想要的,因为您希望被告知错误)。要也重定向错误输出,请使用some-command &> /dev/null
伊利亚·卡根

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

2

尽管您可以在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}

2

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

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

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

goaccess显示帮助页面,而不是创建报告。在外壳中可以用

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

2

就我而言,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 ~ $

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

2

在我的RHEL7服务器上,将运行root cron作业,但不会运行用户作业。我发现没有主目录,作业将无法运行(但您会在/ var / log / cron中看到良好的错误)。当我创建主目录时,问题已解决。


2

如果您使用Windows编辑器(通过samba或其他方式)编辑了crontab文件,并且用\ n \ r或只是\ r替换了换行符,则cron将无法运行。

另外,如果您使用的是/etc/cron.d/*并且其中一个文件带有\ r,则cron会在文件中移动并在遇到错误文件时停止。不知道这是问题吗?

采用:

od -c /etc/cron.d/* | grep \r
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.