Linux学习-54-循环执行定时任务(crontab命令)

114 篇文章 8 订阅
12.20 crontab命令:循环执行定时任务
  • at 命令在指定的时间仅能执行一次任务,但在实际工作中,系统的定时任务一般是需要重复执行的这就需要使用 crontab 命令来执行循环定时任务,而crontab 命令需要 crond 服务支持。crond 是 Linux 下用来周期地执行某种任务或等待处理某些事件的一个守护进程,和 Windows 中的计划任务有些类似。crond 服务的启动和自启动方法如下:
[root@CncLucZK ~]# service crond start
Redirecting to /bin/systemctl start crond.service
[root@CncLucZK ~]# ps aux | grep crond
root        1351  0.0  0.1  36088  3364 ?        Ss   Oct19   0:04 /usr/sbin/crond -n
root     1430590  0.0  0.0  12112  1084 pts/0    S+   12:21   0:00 grep --color=auto crond
#或者重启服务
[root@CncLucZK ~]# service crond restart
Redirecting to /bin/systemctl restart crond.service


#设定crond服务为开机自启动
[root@CncLucZK ~]# chkconfig crond on

在安装完成操作系统后,默认会安装 crond 服务工具,且 crond 服务默认就是自启动的。crond 进程每分钟会定期检查是否有要执行的任务,如果有,则会自动执行该任务。

  • crontab 命令。该命令和 at 命令类似,也是通过 /etc/cron.allow 和 /etc/cron.deny 文件来限制某些用户是否可以使用 crontab 命令的。而且原则也非常相似:

    • 当系统中有 /etc/cron.allow 文件时,只有写入此文件的用户可以使用 crontab 命令,没有写入的用户不能使用 crontab 命令。同样,如果有此文件,/etc/cron.deny 文件会被忽略,因为 /etc/cron.allow 文件的优先级更高。
    • 当系统中只有 /etc/cron.deny 文件时,写入此文件的用户不能使用 crontab 命令,没有写入文件的用户可以使用 crontab 命令。
    • 这个规则基本和 at 命令的规则一致,同样是 /etc/cron.allow 文件比 /etc/cron.deny 文件的优先级高,Linux 系统中默认只有 /etc/cron.deny 文件。
  • 每个用户都可以实现自己的 crontab 定时任务,只需使用这个用户身份执行“crontab -e”命令即可。当然,这个用户不能写入 /etc/cron.deny 文件。crontab 命令的基本格式如下:

[root@localhost ~]# crontab [选项] [file]
#注意,这里的 file 指的是命令文件的名字,表示将 file 作为 crontab 的任务列表文件并载入 crontab
#若在命令行中未指定文件名,则此命令将接受标准输入(键盘)上键入的命令,并将它们键入 crontab。
  • 常用的选项及功能。

    选项功能
    -u user用来设定某个用户的 crontab 服务,例如 “-u demo” 表示设备 demo 用户的 crontab 服务,此选项一般有 root 用户来运行。
    -e编辑某个用户的 crontab 文件内容。如果不指定用户,则表示编辑当前用户的 crontab 文件。
    -l显示某用户的 crontab 文件内容,如果不指定用户,则表示显示当前用户的 crontab 文件内容。
    -r从 /var/spool/cron 删除某用户的 crontab 文件,如果不指定用户,则默认删除当前用户的 crontab 文件。
    -i在删除用户的 crontab 文件时,给确认提示。
  • crontab 定时任务非常简单,只需执行“crontab -e”命令,然后输入想要定时执行的任务即可。不过,当我们执行“crontab -e”命令时,打开的是一个空文件,而且操作方法和 Vim 是一致的。那么,这个文件的格式才是我们真正需要学习的内容。文件格式如下:

[root@localhost !]# crontab -e
#进入 crontab 编辑界面。会打开Vim编辑你的任务
* * * * * 执行的任务
  • 这个文件中是通过 5 个“”来确定命令或任务的执行时间的,这 5 个“”的具体含义:

    项目含义范围
    第一个"*"一小时当中的第几分钟(minute)0~59
    第二个"*"一天当中的第几小时(hour)0~23
    第三个"*"一个月当中的第几天(day)1~31
    第四个"*"一年当中的第几个月(month)1~12
    第五个"*"一周当中的星期几(week)0~7(0和7都代表星期日)
  • 在时间表示中,还有一些特殊符号需要学习:

    特殊符号含义
    *(星号)代表任何时间。比如第一个"*"就代表一小时种每分钟都执行一次的意思。
    ,(逗号)代表不连续的时间。比如"0 8,9,10***命令"就代表在每天的 8点 0 分、9 点 0 分、10点 0 分都执行一次命令。
    -(中杠)代表连续的时间范围。比如"0 1 ** 1-6命令",代表在周一到周六的凌晨 1 点 0 分执行命令。
    /(正斜线)代表每隔多久执行一次。比如"/30***命令",代表每隔半就执行一次命令。
  • 当“crontab -e”编辑完成之后,一旦保存退出,那么这个定时任务实际就会写入 /var/spool/cron/ 目录中,每个用户的定时任务用自己的用户名进行区分。而且 crontab 命令只要保存就会生效,只要 crond 服务是启动的。

  • crontab举例:

    • 10 8***命令 在 8点 10分执行命令
    • 0 15 1,15**命令: 在每月 1 日和 15 日的15 点 0 分执行命令
    • 0/10 15 * * 1,2命令 : 在每周 1,2 日和 15 日的15 点每隔10分钟执行命令
    • 0/10 15 1,15 * 1:在每月 1 日和 15 日,每周1的15 点 0 分都会执行命令,注意:星期几和几日最好不要同时出现,因为它们定义的都是天,非常容易让管理员混淆
  • 执行的任务:字段中可以定时执行系统命令,也可以定时执行某个 Shell 脚本

  • 让系统每隔 10 分钟就向/test/crontab.log 文件中写入一行“hello crontab”,验证一下系统定时任务是否会执行。

[root@CncLucZK cron]# crontab -u zk -e		#指定zk用户的定时任务
#进入编辑界面
*/10 * * * * /bin/echo 'hello crontab' >> /test/crontab.log
[root@CncLucZK cron]# ll /var/spool/cron
total 8
-rw------- 1 root root 107 Jun 29  2021 root
-rw------- 1 root root  60 Oct 26 13:25 zk

这个任务在时间工作中没有任何意义,但是可以很简单地验证我们的定时任务是否可以正常执行。如果觉得每隔 10 分钟太长,那就换成“*”,让它每分钟执行一次。而且和 at 命令一样,如果我们定时执行的是系统命令,那么最好使用绝对路径。

  • 让系统在每周1的凌晨 0 点 0 分重启一次。
[root@CncLucZK test]# crontab -u zk -e
0 0 * * 1 /sbin/shutdown -r now

如果服务器的负载压力比较大,则建议每周重启一次,让系统状态归零。比如绝大多数游戏服务器每周维护一次,维护时最主要的工作就是重启,让系统状态归零。这时可以让我们的服务器自动来定时执行。

  • 在每月 1 日、5日、15 日的凌晨 2 点 0 分都定时执行日志备份脚本 autobak.sh。
[root@CncLucZK test]# crontab -u zk -e
0 2 1,5,15 * * /root/sh/sutobak.sh
  • 这些定时任务保存之后,就可以在指定的时间执行了。我们可以使用命令来查看和删除定时任务,命令如下:
[root@CncLucZK test]# crontab -l -u zk
#查看zk用户的crontab任务
*/10 * * * * /bin/echo 'hello crontab' >> /test/crontab.log
0 0 * * 1 /sbin/shutdown -r now
0 2 1,5,15 * * /root/sh/sutobak.sh
[root@CncLucZK ~]# crontab -r  -u zk
#删除zk用户所有的定时任务。如果只想删除某个定时任务,则可以执行“crontab -e”命令进入
#编辑模式手工删除
[root@CncLucZK ~]# crontab -l
no crontab for zk
#删除后,再查询就没有zk用户的定时任务了
  • 在书写 crontab 定时任务时,需要注意以下几个事项:

    • 6 个选项都不能为空,必须填写。如果不确定,则使用“*”代表任意时间。
    • crontab 定时任务的最小有效时间是分钟,最大有效时间是月。像 2018 年某时执行、3 点 30 分 30 秒这样的时间都不能被识别。
    • 在定义时间时,日期和星期最好不要在一条定时任务中出现,因为它们都以天为单位,非常容易让管理员混淆。
    • 在定时任务中,不管是直接写命令,还是在脚本中写命令,最好都使用绝对路径。有时使用相对路径的命令会报错。
  • 系统的crontab设置:“crontab -e”是每个用户都可以执行的命令,也就是说,不同的用户身份可以执行自己的定时任务。但是有些定时任务需要系统执行,这时就需要编辑 /etc/crontab 这个配置文件了。

  • 当然,并不是说写入 /etc/crontab 配置文件中的定时任务在执行时不需要用户身份,而是“crontab -e”命令在定义定时任务时,默认用户身份是当前登录用户。而在修改 /etc/crontab 配置文件时,定时任务的执行者身份是可以手工指定的。这样定时任务的执行会更加灵活,修改起来也更加方便。

[root@CncLucZK test]# cat /etc/crontab		#查看/etc/crontab内容
#标识使用哪种Shell
SHELL=/bin/bash
#指定PATH环境变量。crontab使用自己的PATH,而不使用系统默认的PATH,所以在定时任务中出现的
#命令最好使用大写
PATH=/sbin:/bin:/usr/sbin:/usr/bin
#如果有报错输出,或命令结果有输出,则会向root发送信息
MAILTO=root

#标识主目录 CentOS 6.x 中
#HOME=/

#提示“man 4 crontabs”查看帮助
# For details see man 4 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) OR sun,mon,tue,wed,thu,fri,sat
# |  |  |  |  |
# *  *  *  *  * user-name  command to be executed
#分 时日月周执行者身份命令
#列出文件格式,并加入了注释
  • 在 CentOS 7.x 中,/etc/crontab 文件也发生了变化。在 CentOS 5.x 中,这个文件的内容大概是这样子的:
#以下输出在CentOS 5.5中
[root@CncLucZK ~]# cat /etc/crontab
SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=root
HOME=/
# run-parts
01 * * * * root run-parts /etc/cron.hourly
02.4 * * * root run-parts /etc/cron.daily
22.4 * * 0 root run-parts /etc/cron.weekly
42.4 1 * * root run-parts /etc/cron.monthly
  • 在 CentOS 5.x 中,/etc/crontab 文件会使用 run-parts 脚本执行 /etc/cron.{hourly,daily,weekly,monthly} 目录中的所有文件。这个 run-parts 其实是一个 Shell 脚本,保存在 /usr/bin/run-parts 中,它的作用就是把其后面跟随的目录中的所有可执行文件依次执行。也就是说,如果我们想让某个脚本在每天都执行一次,那么可以不用手工去写定时任务,而只需要给这个脚本赋予执行权限,并把它放入 /etc/cron.daily/ 目录中,这样这个脚本就会在每天的凌晨 4 点 02 分执行了。

  • 但是在 CentOS 7.x 中,/etc/crontab 文件中不再有相关的段落,那么 run-ptars 这种定时任务的执行方法是否不可用了呢?

    我们看到 /etc/crontab 中有一句提示,让我们“man 4 crontabs”来查看帮助,那么我们就看看这个帮助吧!在这个帮助中,写明了“在旧版本的 crontab 配置文件中,通过 run-parts 脚本来调用 cron.{daily,weekly,monthly} 目录,定时执行这些目录中的脚本。在当前系统中,为了避免 cron 和 anacron 之间产生冲突,只要 anacron 已经安装,就使用 anacron 来执行这些目录中的脚本。具体可以查看 anacron(8) 的帮助”。

  • 对用户来讲,并不需要知道这个定时任务到底是由哪个程序调用的。我们需要知道的事情是如何使用系统的 crontab 设置。对此,新、老版本的 CentOS 没有区别,配置方法都有两种。第一种方法就是把需要定时执行的工作写成脚本程序,并赋予执行权限,然后直接把这个脚本复制到 /etc/cron.{daily,weekly,monthly} 目录中的任意一个。比如,我需要让某个脚本每周执行,就把这个脚本复制到 /etc/cron.weekly/ 目录中。这样这个脚本就会每周执行一次,具体的执行时间要参考 anacron 的配置文件。

  • 第二种方法就是修改 /etc/crontab 这个配置文件,加入自己的定时任务,不过需要注意指定脚本的执行者身份。例如:

[root@CncLucZK ~]# vi /etc/crontab
...
* * * * * root run-parts /test/cron/
#让系统每分钟都执行一次/test/cron/目录中的脚本,脚本执行者是root用户
#虽然在CentOS 6.x中不直接通过此配置文件调用/etc/cron.{daily,weekly,monthly}这些目录,但是run-parts脚本还是可以使用的。所以我完全可以参照CentOS 5.x的方法来写定时任务
#使用run-parts脚本调用并执行/test/cron/目录中所有的可执行文件
#建立/test/cron/目录
[root@CncLucZK test]# mkdir cron
#在/test/cron/hello.log文件中写入“hello”
[root@CncLucZK cron]# vi /test/cron/test.sh
#!/bin/bash
echo 'hello linux' >> /test/cron/cron.log
#赋予执行权限
[root@CncLucZK test]# chmod 755 cron/test.sh
#因为test.sh脚本放入了/test/cron/目录中,所以每分钟执行一次。

[root@CncLucZK test]# cd cron
[root@CncLucZK cron]# ll
total 8
-rw-r--r-- 1 root root 12 Oct 26 14:28 cron.log
-rwxr-xr-x 1 root root 54 Oct 26 14:26 test.sh
[root@CncLucZK cron]# cat cron.log
hello linux
hello linux
  • 只要保存 /etc/crontab 文件,这个定时任务就可以执行了。当然要确定 crond 服务是运行的。这两种方法都是可以使用的。不过,要想修改 /etc/crontab 文件,必须是 root 用户,普通用户不能修改,只能使用用户身份的 crontab 命令。

参考文献:
Linux crontab命令:循环执行定时任务(详解版)

下一篇:Linux学习-55-查看目前和历史登录系统的用户信息(w/who、last/last、lastlog命令)
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值