Linux环境经常需要定时做一些任务,如定时关机、定时下tar包、定时发邮件等。
本文将对常用的Linux定时任务操作方式做一整理。

at

  • 一种在特定日期、时间安排一次性任务的 Linux 终端方法(关键词一次),适合那些 7×24 小时不间断运行的机器上;
  • 可精确到分钟;
  • 两种使用方式:

交互式:

at 09:00 AM
at> echo "hello world" > ~/at-test.txt
at> CTRL+D

非交互式:

echo "echo 'hello world' >> ~/at-test.txt" | at now +1 minute

crontab

  • 用来让使用者在固定时间或固定间隔执行程序之用(关键词多次),适合那些 7×24 小时不间断运行的机器上;
  • 和at一样,可精确到分钟;
  • 几个组件:
    cron 是 linux 中运行例行性工作的一个服务;
    守护进程是crond(/usr/sbin/crond);
    配置接口是crontab;
  • /etc/crontab的格式:
# 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
  • 注意事项:
  • 选项不能为空,必须填写,如不确定,可使用“*”代表任意时间;
  • 定时任务最小有效时间是分钟,最大有效时间是月;
  • 在定时任务中,不管是直接写命令,还是在脚本中写命令,最好都使用绝对路径。有时使用相对路径的命令会报错。
  • 定时交互任务
    如果需要定时做些交互类任务,如登陆交换机,通常使用crond配合expect的方式实现。

anacron

  • crontab的定时在关机之后,就无能为力了,anacron则应运而生,anacron可保证在系统关机时错过的定时任务可以在系统开机之后在执行,anacron需要依赖crond服务来实现;
  • anacron运行机制:
    – anacron会以 1 天、1周(7天)、1个月(最小粒度为1天)作为检测周期,判断是否有定时任务在关机之后没有执行,所以仅能精确到天;
    – 在系统的 /var/spool/anacron/ 目录中存在 cron.{daily,weekly,monthly} 文件,用于记录上次执行 cron 的时间。
    – 将记录的时间与当前时间作比较,若两个时间差超过了 anacron 的指定时间差值,证明有cron任务被漏执行。
  • anacrontab文件格式:
[qxhgd@localhost]$cat /etc/anacrontab
# /etc/anacrontab: configuration file for anacron

# See anacron(8) and anacrontab(5) for details.

SHELL=/bin/sh
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
HOME=/root
LOGNAME=root

# These replace cron's entries
1       5       cron.daily      run-parts --report /etc/cron.daily
7       10      cron.weekly     run-parts --report /etc/cron.weekly
@monthly        15      cron.monthly    run-parts --report /etc/cron.monthly
  • 以 cron.daily 为例说明 anacron 执行过程
    – 从 /etc/anacrontab 分析到 cron.daily 的天数为 1 天。
    从 /var/spool/anacron/cron.daily 中获取最后一次执行 anacron 的时间。
    – 将上面获取的时间与当前时间做对比,若相差时间为1天以上(含一天),就准备执行 cron.daily
    – 根据 /etc/anacrontab 的设置,将延迟5分钟执行 cron.daily。
    – 5分钟后,开始执行 run-parts --report /etc/cron.daily 命令,即执行 /etc/cron.daily 目录下的所有可执行文件。

systemd.timer

  • systemd.timer作为 Linux 的系统启动器,功能强大,用于定时有点大材小用:
    – crontab可以做到的,systemd都可以做到,但反之不是;
    – systemd.timer可以做到精确到秒的;
    – Systemd 取代了initd,成为系统的第一个进程(PID 等于 1),其他进程都是它的子进程;
    – systemd可以在特定事件发生后的一段时间后触发一段脚本或者程序去执行,
  • systemd中有服务单元的概念,定时需要用到其中的两种:.service和.timer。其中.service负责配置需要运行的任务,.timer负责配置执行时间。
  • 一个例子:

– 创建任务脚本:

cat /root/temp/ping252.sh 
#!/bin/bash
ping -c1 10.0.1.252 &>> /root/temp/252.log

– 创建.service:

[qxhgd@localhost]#cd /usr/lib/systemd/system
[qxhgd@localhost system]# cat ping252.service 
[Unit]
Description=ping 252

[Service]
Type=simple
ExecStart=/root/temp/ping252.sh

– 配置.service:

[qxhgd@localhost]# cd /usr/lib/systemd/system
[qxhgd@localhost system]# cat ping252.timer 
[Unit]
Description=ping 252 every 30s

[Timer]
# Time to wait after enable this unit
OnActiveSec=60
# Time between running each consecutive time
OnUnitActiveSec=30
Unit=ping252.service

[Install]
WantedBy=multi-user.target

– 启动定时器

[qxhgd@localhost]# systemctl enable ping252.timer
Created symlink from /etc/systemd/system/multi-user.target.wants/ping252.timer to /usr/lib/systemd/system/ping252.timer.
[qxhgd@localhost system]# systemctl start ping252.timer

– 查看.service和.timer的状态:

#时间
[qxhgd@localhost]# systemctl status ping252.timer
#服务
[qxhgd@localhost]# systemctl status ping252

– 停用定时器

[root@centos7 system]# systemctl disable ping252.timer 
Removed symlink /etc/systemd/system/multi-user.target.wants/ping252.timer.
[root@centos7 system]# systemctl stop ping252.timer
  • Systemd比较重量级,可以写一本书的。

自动化Ansible

  • Ansible是一种自动化的运维工具,基于Python开发,它集合了众多运维工具(比如puppet、chef、func等)的优点,能够实现批量操作。
  • Ansible 是个与 Puppet, SaltStack, Chef 并驾齐驱的组态设定 (Infrastructure as Code) 工具,其简单易用的特性让人爱不释手,在 DevOps 界更佔有一席之地。
  • 一个例子“每两个小时执行ban_try_login_ip.sh”:
ansible all  -m cron  -a  'name="ban IP of login" minute=* hour=*/2 day=* month=* weekday=* job="sh /data/x5online/ban_try_login_ip.sh"'

本文涉及命令汇总

  • at
at [options] [TIME]    #at命令格式

at -V                  #查看at版本,以确认是否安装at version 3.1.13

at 09:00 AM
at> your cmd   #定时的命令
at> CTRL+D     #必须以CTRL+D结束

echo   "your cmd" | at now +1 minute  #1分钟以后执行your cmd
printf "your cmd" | at now +1 minute  #1分钟以后执行your cmd

service atd start      #启动atd服务
systemctl enable --now atd #也可以启动atd服务
service atd  stop      #关闭服务
service atd restart   #重启服务
service atd reload    #重新载入配置
service atd status    #查看服务状态 

atq                   #查看at队列
atrm 1                #删除at队列里1号任务

cat /var/spool/at     #查看存储设置好的at计划任务的目录
cat /etc/at.allow     #查看允许使用at命令的用户,白名单,优先级高于黑命单
cat /etc/at.deny      #查看禁止使用at命令的用户,黑名单
  • crontab
crontab -e         #-e:执行文字编辑器来设定定时任务
crontab -l         #-l:列出目前所有定时任务
crontab -r         #-r:删除目前所有定时任务(慎用)

ps -aux | grep cron #查看cron的状态
service cron start   #启动服务
service cron stop    #关闭服务
service cron restart #重启服务
service cron reload  #重新载入配置
service cron status  #查看服务状态

cat /etc/crontab #查看系统任务调度的配置文件

cat /var/log/cron     #查看已经执行过的任务
tail -f /var/log/cron #查看已经执行过的任务

/etc/cron.deny #该文件中所列用户不允许使用crontab命令
/etc/cron.allow #该文件中所列用户允许使用crontab命令
/var/spool/cron/

man 4 crontabs
  • anacron
anacron [options] [job] #重新执行定时任务
cat  /etc/anacrontab #查看登记的anacron任务
ls -l /var/spool/anacron/ #cron之前执行的记录,如时间等,用于和当前时间进行比较
total 12
-rw------- 1 root root 9 Jun  1 10:25 cron.daily 
-rw------- 1 root root 9 May 27 11:01 cron.monthly
-rw------- 1 root root 9 May 30 10:28 cron.weekly

– systemd.timer

# 查看配置的.service和.timer:
[qxhgd@localhost]#cd /usr/lib/systemd/system
[qxhgd@localhost system]# cat ping252.service 
[qxhgd@localhost system]# cat ping252.timer 

# 使能定时器:
[qxhgd@localhost]# systemctl enable ping252.timer
[qxhgd@localhost]# systemctl start ping252.timer

# 查看定时器和服务状态:
[qxhgd@localhost]# systemctl status ping252.timer
[qxhgd@localhost]# systemctl status ping252

# 关闭定时器:
[qxhgd@localhost]# systemctl disable ping252.timer 
[qxhgd@localhost]# systemctl stop ping252.timer