在 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 的系统管理至关重要。他们对调度和自动化任务提供了一个健壮且通用的工具。