Linux任务计划、周期性任务执行
简要说明
如果想要在未来的某个时间点执行某任务,可以使用命令:
# at
# batch
如果想要周期性的运行某任务,可以使用命令(执行结果会通过邮件发送给用户):
# crontab
mail 服务
mail 进程
可使用如下两个命令,查看 mail 进程是否启动。
# netstat -tnlp
# ss -tnl
有端口25的进程代表mail进程已经启动:IPv4的本地地址是 127.0.0.1:25;IPv6的本地地址是 ::1:25 。
# ss -tnl
State Recv-Q Send-Q Local Address:P Peer Address:Port
LISTEN 0 128 *:22 *:*
LISTEN 0 100 127.0.0.1:2 *:*
LISTEN 0 128 :::*
LISTEN 0 100 ::1:25 :::*
# netstat -tnlp
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 23842/sshd
tcp 0 0 127.0.0.1:25 0.0.0.0:* LISTEN 8853/master
tcp6 0 0 :::22 :::* LISTEN 23842/sshd
tcp6 0 0 ::1:25 :::* LISTEN 8853/master
本地电子邮件服务
- smtp:simple mail transmission protocol
- pop3:Post Office Procotol
- imap4:Internet Mail Access Procotol
mail 命令
# mailx - send and receive Internet mail
平时使用的邮箱软件或者web邮箱称作 MUA 。
# MUA:Mail User Agent, 用户收发邮件的工具程序
命令格式:
# mailx [-s 'SUBJECT'] username[@hostname]
# 通一个主机下的不同用户之间发送邮件可以省略 [@hostname]
# 邮件也可以不带主题
邮件正文的生成的三种方式:
(1) 交互式输入
# . 单独成行可以表示正文结束
# Ctrl+d提交亦可
(2) 通过输入重定向
(3) 通过管道
每个用户都有一个类似于“邮筒”的目录,如下:
[root@LeeMumu ~]# ls /var/spool/mail/
a1 aa b1 JC1 JC3 JC6 JC9 Lee1 Lee3 Lee6 Lee9 ss test4 user12 user21 user33
a2 asd b2 JC10 JC4 JC7 Lee10 Lee4 Lee7 rr test user1 user13 user22
a3 asdasd b3 JC2 JC5 JC8 Lee2 Lee5 Lee8 sd test1 user11 user2 user3
mail 示例
JC1 发送邮件给 root,利用多种方式编写邮件正文:
[JC1@LeeMumu ~]$ mailx -s 'hello' root
Hello!
.
EOT
[JC1@LeeMumu ~]$ cat /etc/issue | mailx -s 'hello1' root
切换到 root 用户,去查收邮件:
[root@LeeMumu ~]# mail
Heirloom Mail version 12.5 7/5/10. Type ? for help.
"/var/spool/mail/root": 2 messages 2 new
>N 1 JC1@LeeMumu.localdom Thu Jul 25 11:51 18/585 "hello"
N 2 JC1@LeeMumu.localdom Thu Jul 25 11:52 20/602 "hello1"
& 1
Message 1:
From JC1@LeeMumu.localdomain Thu Jul 25 11:51:40 2019
Return-Path: <JC1@LeeMumu.localdomain>
X-Original-To: root
Delivered-To: root@LeeMumu.localdomain
Date: Thu, 25 Jul 2019 11:51:40 -0400
To: root@LeeMumu.localdomain
Subject: hello
User-Agent: Heirloom mailx 12.5 7/5/10
Content-Type: text/plain; charset=us-ascii
From: JC1@LeeMumu.localdomain
Status: R
Hello!
& 2 # 输入数字可查看相应邮件内容
Message 2:
From JC1@LeeMumu.localdomain Thu Jul 25 11:52:57 2019
Return-Path: <JC1@LeeMumu.localdomain>
X-Original-To: root
Delivered-To: root@LeeMumu.localdomain
Date: Thu, 25 Jul 2019 11:52:57 -0400
To: root@LeeMumu.localdomain
Subject: hello1
User-Agent: Heirloom mailx 12.5 7/5/10
Content-Type: text/plain; charset=us-ascii
From: JC1@LeeMumu.localdomain
Status: R
\S
Kernel \r on an \m
& q # 输入 q 退出邮箱
Held 2 messages in /var/spool/mail/root
at
用于在指定时间执行命令。at 允许使用一套相当复杂的指定时间的方法。
at 命令
命令格式和选项:
# at [OPTION]... TIME
# TIME:
HH:MM [YYYY-mm-dd] # 指定具体时间
noon, midnight, teatime # 指定模糊时间(中午12点、晚上12点、下午4点)
tomorrow # 明天
now+# # 现在的时间之后执行
UNIT:minutes, hours, days, OR weeks
# 常用选项:
-l:查看作业队列,相当于 atq
-f /PATH/FROM/SOMEFILE:从指定文件中读取作业任务,而不用再交互式输入
-d:删除指定的作业,相当于 atrm
-c:查看指定作业的具体内容
-q QUEUE:指明队列
注意事项:
# at 的作业有队列,用单个字母表示,默认都使用a队列
# 作业执行结果是以邮件发送给提交作业的用户
# 使用 Ctrl+d 退出 at 命令
at 示例
在安装完 at 程序# yum -y install at
时,如果在执行 at 命令时,提示Can't open /var/run/atd.pid to signal atd. No atd running?
可按照如下操作步骤解决。
[root@LeeMumu ~]# chkconfig --level 35 atd on
Note: Forwarding request to 'systemctl enable atd.service'.
[root@LeeMumu ~]#
[root@LeeMumu ~]# service atd start
Redirecting to /bin/systemctl start atd.service
示例1如下:
[root@LeeMumu ~]# at now+2min
at> ls
at> <EOT>
job 8 at Thu Jul 25 12:11:00 2019
[root@LeeMumu ~]#
[root@LeeMumu ~]# at -l
8 Thu Jul 25 12:11:00 2019 a root
[root@LeeMumu ~]# atq
8 Thu Jul 25 12:11:00 2019 a root
[root@LeeMumu ~]# at -c 8 # 查看指定作业的具体内容
#!/bin/sh
# atrun uid=0 gid=0
# mail root 0
umask 22
... ...
MAIL=/var/spool/mail/root; export MAIL
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin; export PATH
PWD=/root; export PWD
LANG=en_US.UTF-8; export LANG
ls # 除了最后是要执行的命令,其它全是一些环境变量
marcinDELIMITER70de07e4
[root@LeeMumu ~]# mail # 执行结束后会以邮件形式通知,可通过邮件查看执行结果
Heirloom Mail version 12.5 7/5/10. Type ? for help.
"/var/spool/mail/root": 3 messages 1 new
1 JC1@LeeMumu.localdom Thu Jul 25 11:51 19/596 "hello"
2 JC1@LeeMumu.localdom Thu Jul 25 11:52 21/613 "hello1"
>N 3 root Thu Jul 25 12:14 46/840 "Output from your job 8"
& 3
Message 3:
From root@LeeMumu.localdomain Thu Jul 25 12:14:29 2019
Return-Path: <root@LeeMumu.localdomain>
X-Original-To: root
Delivered-To: root@LeeMumu.localdomain
Subject: Output from your job 8
To: root@LeeMumu.localdomain
Date: Thu, 25 Jul 2019 12:14:29 -0400 (EDT)
From: root@LeeMumu.localdomain (root)
Status: R
123.txt
1.ciphertext
... ...
ww.sh
& q
Held 3 messages in /var/spool/mail/root
示例2如下(可以从文件中服务任务列表):
[root@LeeMumu ~]# cat at.txt
echo "Hello!"
echo "Hello Again!"
[root@LeeMumu ~]# at now+1min < at.txt
job 9 at Thu Jul 25 12:21:00 2019
[root@LeeMumu ~]# atq
9 Thu Jul 25 12:21:00 2019 a root
[root@LeeMumu ~]# mail
Heirloom Mail version 12.5 7/5/10. Type ? for help.
"/var/spool/mail/root": 4 messages 1 new
1 JC1@LeeMumu.localdom Thu Jul 25 11:51 19/596 "hello"
2 JC1@LeeMumu.localdom Thu Jul 25 11:52 21/613 "hello1"
3 root Thu Jul 25 12:14 47/851 "Output from your job 8"
>N 4 root Thu Jul 25 12:21 15/503 "Output from your job 9"
& 4
Message 4:
From root@LeeMumu.localdomain Thu Jul 25 12:21:00 2019
Return-Path: <root@LeeMumu.localdomain>
X-Original-To: root
Delivered-To: root@LeeMumu.localdomain
Subject: Output from your job 9
To: root@LeeMumu.localdomain
Date: Thu, 25 Jul 2019 12:21:00 -0400 (EDT)
From: root@LeeMumu.localdomain (root)
Status: R
Hello!
Hello Again!
& q
Held 4 messages in /var/spool/mail/root
batch 命令
batch会让系统自行选择在系统资源较空闲的时间去执行指定的任务。
其它使用方法与 at 一致。
周期性任务计划:cron
cron 服务程序是由 cronie 主程序包实现的。
# cronie:主程序包,提供了crond守护进程及相关辅助工具
确保crond守护进程(daemon)处于运行状态:
CentOS 7:
# systemctl status crond.service
# Active: active (running) ... ...
CentOS 6:
# service crond status
#... is running.
[root@LeeMumu ~]# sysctl status crond.service
sysctl: cannot stat /proc/sys/status: No such file or directory
sysctl: cannot stat /proc/sys/crond/service: No such file or directory
[root@LeeMumu ~]# systemctl status crond.service
● crond.service - Command Scheduler
Loaded: loaded (/usr/lib/systemd/system/crond.service; enabled; vendor preset: enabled)
Active: active (running) since Thu 2019-07-25 12:25:35 EDT; 12s ago
Main PID: 7774 (crond)
CGroup: /system.slice/crond.service
└─7774 /usr/sbin/crond -n
Jul 25 12:25:35 LeeMumu systemd[1]: Started Command Scheduler.
Jul 25 12:25:35 LeeMumu crond[7774]: (CRON) INFO (RANDOM_DELAY will be scaled with factor 46% if used.)
Jul 25 12:25:35 LeeMumu crond[7774]: (CRON) INFO (running with inotify support)
Jul 25 12:25:35 LeeMumu crond[7774]: (CRON) INFO (@reboot jobs will be run at computer's startup.)
向crond提交作业的方式不同于at,它需要使用专用的配置文件,此文件有固定格式,不建议使用文本编辑器直接编辑此文件;要使用crontab命令。
cron 任务分类
- 系统cron任务:主要用于实现系统自身的维护(手动编辑:/etc/crontab文件)
- 用户cron任务:使用命令 crontab 进行创建
系统 cron 配置格式
系统cron的配置格式:/etc/crontab
# SHELL=/bin/bash
# PATH=/sbin:/bin:/usr/sbin:/usr/bin
# MAILTO=root
# 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
注意事项:
-
每一行定义一个周期性任务,共7个字段
* * * * * : 定义周期性时间 user-name : 运行任务的用户身份 command to be executed:任务
-
此处的环境变量不同于用户登录后获得的环境,因此,建议命令使用绝对路径,或者自定义PATH环境变量。
-
执行结果邮件发送给MAILTO指定的用户。
用户 cron 配置格式
用户cron的配置格式:/var/spool/cron/USERNAME
# SHELL=/bin/bash
# PATH=/sbin:/bin:/usr/sbin:/usr/bin
# MAILTO=root
# 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
# | | | | |
# * * * * * command to be executed
注意事项:
- 每行定义一个cron任务,共6个字段。
- 此处的环境变量不同于用户登录后获得的环境,因此,建议命令使用绝对路径,或者自定义PATH环境变量。
- 邮件发送给当前用户。
时间表示法
(1) 特定值
给定时间点有效取值范围内的值
注意:day of week和day of month一般不同时使用
(2) *
给定时间点上有效取值范围内的所有值;表“每..”
(3) 离散取值:,
在时间点上使用逗号分隔的多个值
#,#,#
(4) 连续取值:-
在时间点上使用-连接开头和结束
#-#
(5) 在指定时间点上,定义步长
/#:# 即步长
注意事项:
(1) 指定的时间点不能被步长整除时,其意义将不复存在
(2) 最小时间单位为“分钟”,想完成“秒”级任务,得需要额外借助于其它机制
定义成每分钟任务:而在利用脚本实现在每分钟之内,循环执行多次
示例:
注意第七个和第八个的区别。注意 * 的含义。
(1) 3 * * * * # 每小时执行一次;每小时的第3分
(2) 3 4 * * 5 # 每周执行一次;每周5的4点3分
(3) 5 6 7 * * # 每月执行一次;每月的7号的6点5分
(4) 7 8 9 10 * # 每年执行一次;每年的10月9号8点7分
(5) 9 8 * * 3,7 # 每周三和周日执行;在这两天的9时8分执行一次
(6) 0 8,20 * * 3,7 # 每周三和周日执行;在这两天的8时和20时整点执行
(7) 0 9-18 * * 1-5 # 每周一到周五的9时到18时的整点执行
(8) * 9-18 * * 1-5 # 每周一到周五的9时到18时的每分钟都执行,所以按小时执行时,分钟位一般设为 0
(9) */5 * * * * # 每5分钟执行一次任务
crontab命令
# crontab [-u user] [-l | -r | -e] [-i]
-e:编辑任务;也可以删除某个具体的任务,或使用#号注释掉
# 使用 -e 选项时,就相当于修改 /var/spool/cron/USERNAME 文件
# 不建议直接修改配置文件,使用 -e 选项时,会对新增任务的语法格式进行检查
# 有语法错误时,会提示 “errors in crontab file, can't install.”
# 使用 -e 选项时,会立即生效
-l:列出所有任务
-r:移除所有任务;即删除/var/spool/cron/USERNAME文件
-i:在使用-r选项移除所有任务时提示用户确认
-u user:root用户可为指定用户管理cron任务
注意:
1、运行结果以邮件通知给当前用户;如果拒绝接收邮件,可按照如下进行操作。
# COMMAND > /dev/null
# 使用以上命令时,命令执行结果成功后,会定向到 /dev/null
# 如果执行不成功,还是会发送邮件进行提醒
# COMMAND &> /dev/null
# 使用以上命令时,命令执行结果成功或不成功,都会定向到 /dev/null
# 建议大家确保命令成功执行一次后再进行此配置,避免设置的定时任务一直执行失败
2、定义COMMAND时,如果命令需要用到%,需要对其转义;但放置于单引号中的%不用转义亦可。
3、某任务在指定的时间因关机未能执行,下次开机时,是不会自动执行的。.如果期望某时间因故未能按时执行,下次开机后无论是否到了相应时间点都要执行一次,可使用anacron实现。
示例
1、星期六2点每分钟执行一次 echo “Hello.”
[root@LeeMumu ~]# cat /var/spool/cron/root
# SHELL=/bin/bash
# PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin
# MAILTO=root
* 2 * * 6 /usr/bin/echo "Hello."
[root@LeeMumu ~]# date
Sat Jul 27 02:36:00 EDT 2019
You have new mail in /var/spool/mail/root
[root@LeeMumu ~]# mail
Heirloom Mail version 12.5 7/5/10. Type ? for help.
"/var/spool/mail/root": 8 messages 1 new 3 unread
1 JC1@LeeMumu.localdom Thu Jul 25 11:51 19/596 "hello"
2 JC1@LeeMumu.localdom Thu Jul 25 11:52 21/613 "hello1"
3 root Thu Jul 25 12:14 47/851 "Output from your job 8"
4 root Thu Jul 25 12:21 16/514 "Output from your job 9"
U 5 (Cron Daemon) Sat Jul 27 02:35 26/854 "Cron <root@LeeMumu> /usr/bin/echo "Hello.""
U 6 (Cron Daemon) Sat Jul 27 02:36 26/854 "Cron <root@LeeMumu> /usr/bin/echo "Hello.""
7 (Cron Daemon) Sat Jul 27 02:37 26/855 "Cron <root@LeeMumu> /usr/bin/echo "Hello.""
>N 8 (Cron Daemon) Sat Jul 27 02:38 25/844 "Cron <root@LeeMumu> /usr/bin/echo "Hello.""
& 8
Message 8:
From root@LeeMumu.localdomain Sat Jul 27 02:38:01 2019
Return-Path: <root@LeeMumu.localdomain>
X-Original-To: root
Delivered-To: root@LeeMumu.localdomain
From: "(Cron Daemon)" <root@LeeMumu.localdomain>
To: root@LeeMumu.localdomain
Subject: Cron <root@LeeMumu> /usr/bin/echo "Hello."
Content-Type: text/plain; charset=UTF-8
Auto-Submitted: auto-generated
Precedence: bulk
X-Cron-Env: <XDG_SESSION_ID=5>
X-Cron-Env: <XDG_RUNTIME_DIR=/run/user/0>
X-Cron-Env: <LANG=en_US.UTF-8>
X-Cron-Env: <SHELL=/bin/sh>
X-Cron-Env: <HOME=/root>
X-Cron-Env: <PATH=/usr/bin:/bin>
X-Cron-Env: <LOGNAME=root>
X-Cron-Env: <USER=root>
Date: Sat, 27 Jul 2019 02:38:01 -0400 (EDT)
Status: R
Hello.
& q
2、每12小时备份一次/etc目录至/backups目录中,保存文件 名称格式为“etc-yyyy-mm-dd-hh.tar.xz”。
[root@LeeMumu ~]# crontab -l
0 0,12 * * * /usr/bin/tar -Jcf /tmp/etc-$(date +%F-%H-%M-%S).tar.xz /etc
3、每周2、4、7备份/var/log/secure文件至/logs目录中,文件名格式为“secure-yyyymmdd”。
[root@LeeMumu ~]# crontab -l
* 2 * * 6 /usr/bin/echo "Hello." > /dev/null
# */2 * * * * tar -Jcf /tmp/etc-$(date +%F-%H-%M-%S).tar.xz /etc
0 0 * * 2,4,7 cp /var/log/secure /logs/secure-$(date +%Y%m%d)
4、每两小时取出当前系统/proc/meminfo文件中以S或M开头的行信息追加至/tmp/meminfo.txt文件中。
[root@LeeMumu ~]# crontab -l
* 2 * * 6 /usr/bin/echo "Hello." > /dev/null
# */2 * * * * tar -Jcf /tmp/etc-$(date +%F-%H-%M-%S).tar.xz /etc
0 0 * * 2,4,7 cp /var/log/secure /logs/secure-$(date +%Y%m%d)
0 */2 * * * grep "^[Ss]" /proc/meminfo >> /tmp/meminfo.txt && date +%F-%H-%M-$S >> /tmp/meminfo.txt