这是关于使用cron&crontab的规范问题 。
你已经被引导到这里,因为社区相当确定你的问题的答案可以在下面find。 如果您的问题未在下面得到解答,那么答案将有助于您收集有助于社区帮助您的信息。 这个信息应该被编辑成你原来的问题。
“ 为什么我的crontab无法正常工作,我该如何排除故障? '可以在下面看到。 这就解决了crontab高亮显示的cron
系统。
这是一个社区wiki ,如果你发现这个答案有任何不正确的地方或者有额外的信息,那么请编辑它。
系统上的每个用户都可能拥有自己的crontab文件。 根和用户crontab文件的位置取决于系统,但通常位于/var/spool/cron
。
有一个全系统的/etc/crontab
文件, /etc/crontab
cron.d目录可能包含crontab碎片,这些碎片也可以被cron读取和执行。 一些Linux发行版(例如Red Hat)也有/etc/cron.{hourly,daily,weekly,monthly}
目录,其中的脚本将在每小时/每天/每周/每月执行,并具有root权限。
root始终可以使用crontab命令; 普通用户可能会或可能不会被授予访问权限。 当用命令crontab -e
编辑crontab文件并保存时,crond会检查它是否具有基本的有效性,但不能保证您的crontab文件格式正确。 有一个名为cron.deny
的文件,它将指定哪些用户不能使用cron。 cron.deny
文件的位置取决于系统,可以删除,这将允许所有用户使用cron。
如果计算机未通电或crond守护进程未运行,并且运行命令的date/时间已过,则crond将无法追赶并运行查询。
一个crontab命令由一行代表。 您不能使用\
在多行上扩展命令。 散列( #
)符号表示注释,意味着该行上的任何内容都被cron忽略。 领先的空白和空白行被忽略。
在命令中使用百分比( %
)符号时要格外小心。 除非它们被转义\%
否则它们会被转换成换行符,并且在第一个非转义%
之后的所有内容都会在stdin中传递给您的命令。
有两种格式的crontab文件:
用户crontabs
# Example of job definition: # .---------------- minute (0 - 59) # | .------------- hour (0 - 23) # | | .---------- day of month (1 - 31) # | | | .------- month (1 - 12) OR jan,feb,mar,apr ... # | | | | .---- day of week (0 - 6) (Sunday=0 or 7) # | | | | | # * * * * * command to be executed
系统全/etc/crontab
和/etc/cron.d
分片
# Example of job definition: # .---------------- minute (0 - 59) # | .------------- hour (0 - 23) # | | .---------- day of month (1 - 31) # | | | .------- month (1 - 12) OR jan,feb,mar,apr ... # | | | | .---- day of week (0 - 6) (Sunday=0 or 7) # | | | | | # * * * * * user-name command to be executed
注意后者需要一个用户名。 该命令将以指定的用户身份运行。
该行的前5个字段表示应该运行该命令的时间。 您可以在时间说明中使用数字或适用的date/月份名称。
,
)用于指定一个列表,例如1,4,6,8,表示在1,4,6,8处运行。 -
)指定,并且可以与列表结合,例如1-3,9-12,这意味着在1和3之间,然后在9和12之间。 /
字符可以用于引入一个步骤,例如2/5,这意味着从2开始,然后每5(2,7,12,17,22 …)。 它们不会结束。 *
)表示该字段的整个范围(例如, 0-59
表示分钟字段)。 */2
表示从相关字段的最小值开始,然后每2个例如0分钟(0,2 … 58),1个月(1,3 … 11)等等 检查邮件! 默认情况下,cron会把命令中的所有输出发送给正在运行命令的用户。 如果没有输出,就不会有邮件。 如果你想cron发送邮件到不同的帐户,那么你可以在crontab文件中设置MAILTO环境variables
[email protected] 1 2 * * * /path/to/your/command
捕获输出你自己
1 2 * * * /path/to/your/command &>/tmp/mycommand.log
它将stdout和stderr捕获到/tmp/mycommand.log
看日志; cron通过系统日志logging它的行为,这取决于你的设置,经常进入/var/log/cron
或/var/log/syslog
。
如果需要,你可以用例如过滤cron语句
grep CRON /var/log/syslog
现在我们已经了解了cron的基础知识,文件的位置以及如何使用它们,让我们看看一些常见的问题。
如果cron没有运行,那么你的命令将不会被调度。
ps -ef | grep cron | grep -v grep
应该得到你的东西
root 1224 1 0 Nov16 ? 00:00:03 cron
要么
root 2018 1 0 Nov14 ? 00:00:06 crond
如果不重新启动它
/sbin/service cron start
要么
/sbin/service crond start
可能有其他方法; 使用你的发行版提供的东西。
可用的环境variables可能非常有限。 通常情况下,您只会获得一些定义的variables,如$LOGNAME
, $HOME
和$PATH
。
特别值得注意的是, PATH
仅限于/bin:/usr/bin
。 绝大多数“我的cron脚本不起作用”的问题是由这个限制性的path引起的 。 如果您的命令位于不同的位置,可以通过以下几种方法解决:
提供您的命令的完整path。
1 2 * * * /path/to/your/command
在crontab文件中提供一个合适的PATH
PATH=/usr:/usr/bin:/path/to/something/else 1 2 * * * command
如果你的命令需要其他的环境variables,你也可以在crontab文件中定义它们。
无论执行的程序位于文件系统的什么地方,当cron运行时程序的当前工作目录都将成为用户的主目录 。 如果你在你的程序中访问文件,如果你使用相对path,或者(最好)只是使用完全合格的path,那么你需要考虑这个问题,并为每个人节省很多的困惑。
Cron通常要求命令以新行结束。 编辑你的crontab; 转到包含最后一条命令的行的末尾,并插入一个新行(按回车键)。
您不能在/ etc / crontab中使用用户crontab格式的crontab或/etc/cron.d中的碎片,反之亦然。 用户格式化的crontab在一行的第6个位置不包含用户名,而系统格式化的crontab包含用户名并以该用户的身份运行命令。
#!/bin/sh
放在顶部) 如果您的date最近由用户或系统更新,时区或其他更改,那么crontab将开始行为不正常,并显示奇怪的错误,有时工作,有时不会。 这是crontab试图在时间从它下面改变时尝试“做你想做的事”。 小时改变后,“分钟”字段将无效。 在这种情况下,只有星号才会被接受。 重新启动cron并再次尝试,而不连接到互联网(所以date没有机会重置到其中一个时间服务器)。
如果您的cronjob停止工作,请检查您的密码是否过期,因为一旦它有,所有cron作业停止。
/var/log/messages
中会显示类似于下面的/var/log/messages
,显示validation用户的问题:
(username) FAILED to authorize user with PAM (Authentication token is no longer valid; new one required)
Debian Linux及其派生版(Ubuntu,Mint等)有一些特性,可能会阻止您的cron作业执行; 尤其是/etc/cron.d
的文件必须:
最后一个定期伤害用户; 特别是任何名为whatever.sh
, mycron.py
, testfile.pl
等的文件夹中的任何脚本都不会被执行。
根据我的经验,这个特殊点是Debian和衍生产品上不执行cronjob的最常见原因。
如有必要,请参阅man cron
以获取更多详细信息。
如果你有一些类似cron的工作:
php /bla/bla/something.php >> /var/logs/somelog-for-stdout.log
如果错误期望,他们将被发送给你,但他们不 – 检查这一点。
PHP默认不发送错误到STDOUT。 @请参阅https://bugs.php.net/bug.php?id=22839
要解决这个问题,请添加cli`s php.ini或者你的行(或者你的bash包装中的PHP):
第一个设置将允许你有像“记忆哎呀”和第二个 – redirect到STDERR的致命。 只有当你能睡好之后,所有的东西才会被发送到你的根邮件,而不是只logging下来。
Cron被认为是一个非常基本的调度器,语法不容易让pipe理员制定稍微不寻常的调度。
考虑下面通常会被解释为“每5分钟运行一次command
”的工作 :
*/5 * * * * /path/to/your/command
与:
*/7 * * * * /path/to/your/command
这并不总是每7分钟运行一次command
。
请记住, /字符可以用来引入一个步骤,但是这些步骤不会超出系列的末尾,例如*/7
,从第0-59
分钟开始每7分钟匹配,即0,7,14,21,28 ,35,42,49,56,但在一小时和下一个 之间 , 只有4分钟之间 ,00:56之后新的系列从01:00
开始, 01:00
:07等(批量不会运行01:03
等)。
该怎么做呢?
创build多个批次
而不是一个单一的cron作业,创build多个批次,将所需的时间表结合起来。
例如,每40分钟运行一批(00:00,00:40,01:20,02:00等),创build两个批次,一个在偶数小时运行两次,另一个只运行奇数小时:
# The following lines create a batch that runs every 40 minutes ie # runs on 0:00, 0:40, 02:00, 02:40 04:00 etc to 22:40 0,40 */2 * * * /path/to/your/command # runs on 01:20, 03:20, etc to 23:20 20 1/2 * * * /path/to/your/command # Combined: 0:00, 0:40, 01:20, 02:00, 02:40, 03:20, 04:00 etc.
less运行你的批次
而不是每7分钟运行一次,这是一个很难分批处理的时间表,而是每十分钟运行一次。
更频繁地运行你的批次
由于批处理运行时间增加/波动,因此许多奇怪的进度表会发生变化,然后批处理会得到一些额外的安全余量,从而防止同一批次的后续运行重叠并且同时运行。
相反,换个angular度思考,创build一个cronjob,当前一次运行尚未完成时,将会优雅地失败,但是否则将运行。 看到这个问答 :
* * * * * /usr/bin/flock -n /tmp/fcj.lockfile /usr/local/bin/frequent_cron_job --minutely
不要使用cron
如果你的需求很复杂,你可能会考虑使用一个更高级的产品来devise运行复杂的计划(分布在多个服务器上),并支持触发器,工作依赖,error handling,重试监控等行业术语将是“企业” 工作调度和/或“工作量自动化”。