在 Linux 中的 cron 任务是一个强大的工具,它能够帮助用户执行一些定时任务。这一篇文章就是详细介绍 Linux 中的 cron,可以用它来帮助你自动化一些日常任务。
什么是 Cron
Cron 是 Linux 系统中的基于时间的任务调度器,也可以应用到其他的类 Linux 系统当中。它能够帮在固定的时间,日期或者间隔调度执行任务。比如,常见的系统维护,重要文件的备份等都可以使用 Cron 来完成
Cron 的工作原理
Cron 的核心组件是一个命名为 crond 的守护进程。它主要的任务就是在指定的时间间隔中检查,调度并且执行任务。这个守护进程会每分钟检查一次配置的 crontab file和 crontab directory。
这些 crontab file和 crontab directory是 cron 任务调度系统的核心。其中,crontab(cron table) 指的就是在这些文件中包含的 cron 表达式列表。在这个 crontab file中的每一行都是一个定义好且在固定指定或间隔执行的任务
除了 crontab文件外,大部分的 Linux 系统包含一些列可被 cron 进程扫描的目录,如:*/etc/cron.hourly* , */etc/cron.weekly* , */etc/cron.monthly* 。这些目录的名字就表明了他们的调度时间,比如 /etc/cron.hourly下面脚本就是每小时执行一次
crontab 有两种类型:用户级别的和系统级别的。用户级别的 crontab文件是放在 /var/spool/cron目录下,而系统服务和应用级的的 crontab 文件是放在 etc/cron.d目录下面
Cron 的语法
一个 cron job 就是在 crontab file 中的一行。这一行由空格或者 tab分隔开的字段组成的,这一行的最后就是要执行的命令或者脚本。具体如下:
minute hour day_of_month month day_of_week command_to_execute
Minute(0-59)
这个字段指定了命令在那一分钟执行,比如:0 表示在每小时的开始执行
Hour(0-23)
这个字段指定了命令在哪个小时执行,比如:14 表示在下午两点执行
Day of Month(1-31)
这个字段指定了命令在哪一天执行。例如:1表示在这个月的第一天执行
Month(1-12)
这个字段指定了命令在哪个月执行。例如:3 表示命令在三月执行
Day of Week(0-6)
这个字段指定了命令在这一周的哪一天执行,0 表示周天。例如:5 表示每周五执行
特殊语法
除了上面的这些,还有一些特殊的值,比如:
*:表示每一次,比如:*在Hour字段表示每个小时,:逗号可以指定一个列表,比如:在字段week上 “1,3,4”表示周一,周三,周四执行-:短横线指定一个范围,比如:在Hour上的9-17,表示从早点九点到下午五点每个小时/:这指定了一个增量,比如:在Minute上的*/10表示每十分钟
除了这些以外,还有一些简单的字符表示时间和日期,如下:
@reboot:表示在启动时执行一次@yearly,@annually:表示在每年一月一号12点执行,等同于0 0 1 1 *@monthly:在每个月一号中午12点执行,等同于0 0 1 * *@weekly:在每周周天中午12点执行,等同于0 0 * * 0@daily:每天中午12点执行,等同于0 0 * * *@hourly:每小时执行一次,等同于0 * * * *
创建和管理
上面都是一些理论知识,下面我们来看下如何在 Linux 中创建和管理 cron 任务
创建用户级 cron job
创建的命令如下:
crontab -e
执行之后,会有一个选项列表,让你选择使用哪个编辑器来编辑,具体如下:
在选择了编辑之后,会打开一个文件,文件上面试一下指导创建 cron 任务的文档,我们现在在最下面添加任务:
0 3 * * * /home/xxx/backup.sh
我们添加了一个在每天三点执行的备份的任务,如下:
接着我们保存,然后退出。保存的时候会进行语法检查,保存退出之后就会生效,不需要重启系统。
注:上面的命令也可以编辑用户级的 cron 任务,编辑其他用户的可以使用:
sudo crontab -u bobby -e
创建系统级 cron job
命令 crontab -e是创建用户级的,创建系统级的 cron 任务可以直接编辑 /etc/crontab 文件,命令如下:
sudo vim /etc/crontab
下面我们添加一个任务删除 myservice 的日志,具体如下:
0 2 * * * root /usr/bin/find /var/log/myservice -type f -name '*.log' -delete
具体如下:
上面的 crontab 指定了 root,表示这个任务是在 root 用户下面执行。直接编辑 /etc/crontab 需要注意一些潜在的问题,
比如:
- 这个方法不会进行语法检查,可以会增加错误风险
- 因为这个文件会影响整个系统,不正确的任务可能会对整个系统的安全和稳定造成影响
所以,要谨慎使用
列出任务
使用下面的命令可以列出当前用户所有的 cron 任务:
cron -l
也可以列出其他用户的任务,如下:
sudo crontab -u xxx -l
系统级的任务可以使用如下命令:
sudo cat /etc/crontab
删除 Cron 任务
如果是删除单个任务,那么可以使用上面的 cron -e 进入编辑器,删除对应的条目即可。如果要删除这个用户的所有 cron 任务,可以使用如下命令:
crontab -r
故障排查
因为 cron 任务是无交互式在后台运行的,所以要留意潜在出现的错误,防止任务执行失败或者执行错误。首先,要检查 crontab 的定义是不是正确。接着要确保 crond 在后台运行,命令如下:
sudo systemctl status cron
正常运行的如下图所示:
接着,要确保在 crontab 表达式中指定的命令和脚本是否正确。检查用户是否有执行命令或者脚本的权限。除此之外,还要检查脚本的环境变量。因为 cron 不会自动继承用户或者系统的环境变量
Cron 任务和 Paths
当运行 cron任务的时候,它是在一个受限的环境当中,这意味着它并不继承用户或系统的环境变量。这有可能由于未定义或者错误的 path 导致任务执行失败。因此,需要在 crontab 文件中明确的设置 PATH 环境变量来解决路径的问题。用这个 PATH 告诉 crond 在那去找这个可执行文件,例如:
PATH=/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin
在 crontab 文件的开头添加这一行,确保下面的所有 cron job 在这些目录下搜索可执行文件。
当然,为了保证文件的干净,最好还是指定可执行文件的全路径。还有就是,在保存之前,自己先在终端执行一下,保证能够正确执行。
结语
Cron 任务对于 Linux 的系统管理至关重要。他们对调度和自动化任务提供了一个健壮且通用的工具。