Linux任务计划、周期性任务执行(mail / at / batch / crontab)

本文详细介绍了Linux系统中用于任务计划和周期性任务执行的工具,包括mail服务、at命令、batch命令和crontab。通过实例演示了如何设置定时任务,并发送邮件通知。还讲解了cron任务的配置格式和时间表示法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

简要说明

如果想要在未来的某个时间点执行某任务,可以使用命令:

# 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  

本地电子邮件服务

  1. smtp:simple mail transmission protocol
  2. pop3:Post Office Procotol
  3. 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 任务分类

  1. 系统cron任务:主要用于实现系统自身的维护(手动编辑:/etc/crontab文件)
  2. 用户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

注意事项:

  1. 每一行定义一个周期性任务,共7个字段

    *  *  *  *  * : 定义周期性时间
    user-name : 运行任务的用户身份
    command to be executed:任务
    
  2. 此处的环境变量不同于用户登录后获得的环境,因此,建议命令使用绝对路径,或者自定义PATH环境变量。

  3. 执行结果邮件发送给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

注意事项:

  1. 每行定义一个cron任务,共6个字段。
  2. 此处的环境变量不同于用户登录后获得的环境,因此,建议命令使用绝对路径,或者自定义PATH环境变量。
  3. 邮件发送给当前用户。

时间表示法

(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
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值