linux系统服务定时任务(深入浅出Linux定时任务cron)

我们每天早晨都要起床吃饭,然后上班工作赚钱,如此往复,Linux操作系统也一样,总有一些任务需要定时执行,例如日志轮替、备份、清理垃圾数据等。驱动Linux定时任务系统背后的功臣是 crond 服务。在安装完操作系统后,系统默认会安装 crond 服务,并且默认是开机自动启动,可以检查一下它的工作状态。

# systemctl status crond ● crond.service - Command Scheduler Loaded: loaded (/usr/lib/systemd/system/crond.service; enabled; vendor preset: enabled) Active: active (running) since Fri 2022-12-02 19:56:36 EST; 5 days ago

本文首先带您了解一下都有哪些 cron 配置文件,然后了解一下 cron 如何表示各种周期性时间,以及如何添加到cron中。

linux系统服务定时任务(深入浅出Linux定时任务cron)(1)

cron定时任务

cron 配置文件

Linux系统中的各种服务都有自己的配置文件,cron 服务也不例外,与它相关的配置文件和目录包括:

  • /etc/crontab 全局配置文件
  • /etc/cron.d/
  • /var/spool/cron/ 用户配置文件
  • /etc/cron.deny
  • /etc/cron.hourly/
  • /etc/cron.daily/
  • /etc/cron.weekly/
  • /etc/cron.monthly/

cron 服务会扫描 /etc/crontab 文件,以及 /var/spool/cron/ 目录下的配置文件,并且按照指定的周期去执行它们。不过 /etc/crontab 文件有一个user-name字段,它用来描述运行脚本的用户,而/var/spool/cron/ 目录下的配置文件是以用户名命名的,因此不需要用户名字段。

不推荐直接编辑/etc/crontab文件,而应该使用后面介绍的crontab -e命令添加定时任务。

注意:不同Linux发行版 cron服务的配置文件的内容并不一样,不过原理都差不多,本文实验环境如下所示:

操作系统:AlmaLinux 8.6 客户端:Windows 11 SSH客户端:MobaXterm 21.1 使用的用户:root 同时适用于RockyLinux8、AlmaLinux8、CentOS8,因为它们都是基于RedHat Linux。Ubuntu等操作系统原理也是类似的。

crontab 文件

初始状态下的/etc/crontab文件只是介绍了一下配置语法,没有任何定时任务。

linux系统服务定时任务(深入浅出Linux定时任务cron)(2)

/etc/crontab配置文件

定时任务都是以 “分钟 小时 天 月 周 命令” 形式呈现:

  • 分钟:描述第几分钟运行任务,范围0-59。例如如果该字段等于5,那么将在第5分钟运行任务。
  • 小时:描述第几小时运行任务,范围0-23。例如如果该字段等于3,那么将在凌晨3点运行任务。
  • 天:描述第几天运行任务,范围1-31。例如如果该字段等于3,那么将在第3天运行任务。
  • 月:描述几月运行任务,范围1-12。例如如果该字段等于3,那么将在3月运行任务。
  • 周:描述周几运行任务,范围0-7。例如如果该字段等于3,那么将在星期三运行任务。
  • 命令:任务脚本。

linux系统服务定时任务(深入浅出Linux定时任务cron)(3)

符号

含义

*

任何时间,比如第一个 * 表示每分钟都运行此任务。

,

不连续的时间

-

连续的时间范围

/

每隔多久执行一次

定时任务示例

每一分钟执行一次 /bin/ls:

* * * * * /bin/ls

12月每天早上 6 点到 12 点,每隔 3 小时第 0 分钟执行一次 /usr/bin/backup:

0 6-12/3 * 12 * /usr/bin/backup

周一到周五每天下午 5:00 寄一封信给 alex@domain.name:

0 17 * * 1-5 mail -s "hi" alex@domain.name < /tmp/maildata

每天凌晨 0 点 20 分, 2 点 20 分, 4 点 20 分....执行 echo "haha":

20 0-23/2 * * * echo "haha"

不过实际工作中的时间设置不会这么复杂,一般就是每天几点运行备份脚本之类的。还有人专门编了一个图形化工具,地址:http://www.openjs.com/scripts/jslibrary/demos/crontab.php

linux系统服务定时任务(深入浅出Linux定时任务cron)(4)

添加定时任务

现在我们已经知道了如何编辑定时任务,现在来看看如何将其添加到cron配置文件。

在添加到cron服务到之前,请首先运行一下任务脚本,确保结果符号你的需求。

正确的方法是:使用专门的 crontab 命令,此时会进入vi编辑器,然后输入前面已经设计好的定时任务,最后保存退出vi编辑器。

注意:不要直接编辑 /etc/crontab 文件,而是使用 crontab命令,因为它会在退出编辑时检查语法是否正确。

crontab 命令的几个重要选项

crontab -u 指定用户名,省略用户表表示操作当前用户的crontab -e 编辑任务 -l 列出任务 -r 删除任务

最常使用的就是 e 和 l 选项。

例如root通过输入下面的命令开始编辑定时任务

crontab -e

然后输入两条任务

* * * * * echo $(date "\%Y年\%m月\%d日 \%H时\%M分\%S秒") >> test.txt * * * * * echo `date " \%Y-\%m-\%d \%H:\%M:\%S"` >> test.txt * * * * * echo 1 >> test.txt * * * * * echo 2 >> test.txt * * * * * echo 3 >> test.txt

这个任务会在当前用户家目录test.txt文件中输出当前日期和时间。

从输出信息来看,任务的执行顺序是随机的,并没有什么规律。

2022-12-09 08:59:01 1 2022年12月09日 08时59分01秒 2 3 3 1 2022年12月09日 09时00分01秒 2 2022-12-09 09:00:01

之所以举这个例子是因为折腾了我一阵子,因为它一直不能正常工作,直到搜索了一番才发现 % 需要 转义。

The "sixth" field (the rest of the line) specifies the command to be run. The entire command portion of the line, up to a newline or % character, will be executed by /bin/sh or by the shell specified in the SHELL variable of the cronfile. Percent-signs (%) in the command, unless escaped with backslash (\), will be changed into newline characters, and all data after the first % will be sent to the command as standard input.

"第六"个字段描述希望运行的命令。命令部分以换行或者 % 字符作为结束标志,如果命令需要用到百分比符号(%),必须使用反斜杠(\)转义,否则视为换行符,同时第一个%之后的所有数据将作为标准输入发送到命令中。

如果打开 /etc/crontab ,你会发现这个文件内容没有发生任何变化,刚才以root身份添加的两条任务保存在哪个文件中呢?答案是/var/spool/cron/root。

在大多数Linux发行版中,各个用户的crontabs通常存储在 /var/spool/cron/crontabs/<username>。基于RHEL的发行版则存储在/var/spool/cron/<username>。

如果任务比较复杂,不能在一行中写完,那么可以将任务写在脚本文件中,然后直接调用这个文件。注意需要为脚本文件添加执行权限。

00 02 * * * /usr/bin/bash /home/cron/dbbackup.sh

固定周期任务

对于每小时、每天、每周、每月执行一次的任务,您还可以直接将它们放到下面的文件夹中,cron 服务和anacron会按照指定的周期运行这些目录下的任务。

怎么又多了一个anacron?不要着急,目前只需要记住/etc/cron.hourly/目录中的脚本由cron驱动,而cron.daily、cron.weekly和cron.monthly目录中的脚本由anacron驱动即可,这是因为anacron也有点复杂,我们将在下一篇文章中进行讲解。

  • /etc/cron.hourly/
  • /etc/cron.daily/
  • /etc/cron.weekly/
  • /etc/cron.monthly/

/etc/cron.d/ 目录中只有一个0hourly配置文件,它的内容如下所示:

可以看出0hourly添加了一个每小时执行一次的定时任务,它在每小时的第1分钟以root身份启动 run-parts 执行 /etc/cron.hourly 目录下的脚本。

# cat /etc/cron.d/0hourly # Run the hourly jobs SHELL=/bin/bash PATH=/sbin:/bin:/usr/sbin:/usr/bin MAILTO=root 01 * * * * root run-parts /etc/cron.hourly

而/etc/cron.hourly/目录初始只有一个0anacron脚本,它最后启动了anacron (/usr/sbin/anacron -s),即每小时系统都会运行一次anacron,而anacron又会去干它应该干的一些重要的事情。

# cat /etc/cron.hourly/0anacron #!/bin/sh # Check whether 0anacron was run today already if test -r /var/spool/anacron/cron.daily; then day=`cat /var/spool/anacron/cron.daily` fi if [ `date %Y%m%d` = "$day" ]; then exit 0 fi # Do not run jobs when on battery power online=1 for psupply in AC ADP0 ; do sysfile="/sys/class/power_supply/$psupply/online" if [ -f $sysfile ] ; then if [ `cat $sysfile 2>/dev/null`x = 1x ]; then online=1 break else online=0 fi fi done if [ $online = 0 ]; then exit 0 fi /usr/sbin/anacron -s

查看定时任务运行日志

定时任务运行日志保存在 /var/log/cron 文件中,输入下面的命令可以实时查看文件内容的变化情况

tail -f /var/log/cron

很多系统“被黑”之后,黑客会添加一些定时任务,出现问题的时候看看定时任务执行日志说不定有帮助。

通过查看运行日志也可以进行定时任务错误调试,通常的错误包括:

  • crontab 服务是否正常
  • 脚本是否添加了执行权限
  • 脚本路径前是否添加了 bash 或 /bin/sh
权限

如果希望严格控制哪些用户可以编辑/运行定时任务,可以在文件 /etc/cron.allow 和 /etc/cron.deny 中进行配置,这适用于大多数Linux发行版。编辑或创建 cron.deny 和 cron.allow文件需要root权限。

根据 /etc/cron.allow 和 /etc/cron.deny 是否存在,按照以下顺序判断用户是否可以编辑crontab。

  1. 如果cron.allow存在--只有列在其中的用户可以使用crontab。
  2. 如果cron.allow不存在--除了cron.deny中列出的用户,所有用户都可以使用crontab。
  3. 如果这两个文件都不存在--只有root可以使用crontab。
  4. 如果一个用户同时列在cron.allow和cron.deny中 - 该用户可以使用crontab。
参考文章
  1. Linux日志切割工具Logrotate配置详解
  2. https://unix.stackexchange.com/questions/29578/how-can-i-execute-date-inside-of-a-cron-tab-job
  3. https://www.macgasm.net/news/tips/terminal-tip-scheduling-rsync-backup-ssh-cron-job/
  4. https://www.cyberciti.biz/cloud-computing/why-is-my-linux-unix-crontab-job-not-working/
,

免责声明:本文仅代表文章作者的个人观点,与本站无关。其原创性、真实性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容文字的真实性、完整性和原创性本站不作任何保证或承诺,请读者仅作参考,并自行核实相关内容。文章投诉邮箱:anhduc.ph@yahoo.com

    分享
    投诉
    首页