第十二章 Linux系统管理(进程管理、工作管理和系统定时任务)(三)
十九、Linux 定时执行任务(at命令)
Linux at命令详解:定时执行任务
要想使用 at 命令,读者需提前安装好 at 软件包,并开启 atd 服务。因此,首先来看看如何安装 at 软件包。
在 Linux 系统中,查看 at 软件包是否已安装,可以使用 rpm -q 命令,如下所示:
[root@localhost ~]# rpm -q at
at-3.1.13-20.el7x86_64
可以看到,当前系统已经安装 at 软件包,若读者所用系统未安装,可使用如下命令进行安装:
[root@localhost ~]# yum -y install at
#省略输出信息,最终出现 Complete!,证明安装成功。
除此之外,at 命令要想正确执行,还需要 atd 服务的支持。atd 服务是独立的服务,启动的命令如下:
[root@localhost ~]# service atd start
正在启动 atd: [确定]
如果想让 atd 服务开机时自启动,则可以使用如下命令:
[root@localhost ~]# chkconfig atd on
当然,独立服务的自启动也可以修改 /etc/rc.local 配置文件,具体怎么做看个人习惯。
安装好 at 软件包并开启 atd 服务之后,at 命令才可以正常使用,不过在此之前,我们还要学习一下 at 命令的访问控制。
访问控制指的是允许哪些用户使用 at 命令设定定时任务,或者不允许哪些用户使用 at 命令。大家可以将其想象成设定黑名单或白名单,这样更容易理解。
at 命令的访问控制是依靠 /etc/at.allow(白名单)和 /etc/at.deny(黑名单)这两个文件来实现的,具体规则如下:
- 如果系统中有 /etc/at.allow 文件,那么只有写入 /etc/at.allow 文件(白名单)中的用户可以使用 at 命令,其他用户不能使用 at 命令(注意,/etc/at.allow 文件的优先级更高,也就是说,如果同一个用户既写入 /etc/at.allow 文件,又写入 /etc/at.deny 文件,那么这个用户是可以使用 at 命令的)。
- 如果系统中没有 /etc/at.allow 文件,只有 /etc/at.deny 文件,那么写入 /etc/at.deny 文件(黑名单)中的用户不能使用 at 命令,其他用户可以使用 at 命令。不过这个文件对 root 用户不生效。
- 如果系统中这两个文件都不存在,那么只有 root 用户可以使用 at 命令。
系统中默认只有 /etc/at.deny 文件,而且这个文件是空的,因此,系统中所有的用户都可以使用 at 命令。不过,如果我们打算控制用户的 at 命令权限,那么只需把用户写入 /etc/at.deny 文件即可。
对于 /etc/at.allow 和 /etc/at.deny 文件的优先级,我们做一个实验来验证一下,命令如下:
[root@localhost ~]# ls -l /etc/at*
-rw-r--r--.1 root root 1 1月 30 2012 /etc/at.deny
#系统中默认只有at.deny文件
[root@localhost ~]# echo user1 >> /etc/at.deny
[root@localhost ~]# cat /etc/at.deny
user1
#把user1用户写入/etc/at.deny文件
[root@localhost ~]# su - user1
[user1@localhost ~]$ at 02:00
You do not have permission to use at.
#没有权限使用at命令,切换成user1用户,这个用户已经不能执行at命令了
[user1@localhost ~]$ exit
logout
#返回root身份
[root@localhost ~]# echo user1 >> /etc/at.allow
[root@localhost ~]# cat /etc/at.allow
user1
#建立/etc/at.allow文件,并在文件中写入user1用户
[root@localhost ~]# su - user1
[user1@localhost ~]$ at 02:00
at>
#切换成user1用户,user1用户可以执行at命令。这时user1用户既在/etc/at.deny文件中,又在/etc/at.allow文件中,但是/etc/at.allow文件的优先级更高
[user1@localhost ~]$ exit
logout
#返回root身份
[root@localhost ~]# at 02:00
at>
#root用户虽然不在/etc/at.allow文件中,但是也能执行at命令,
#root用户虽然不在/etc/at.allow文件中,但是也能执行at命令,
#说明root用户不受这两个文件的控制
这个实验说明了 /etc/at.allow 文件的优先级更高,如果 /etc/at.allow 文件存在,则 /etc/at.deny 文件失效。/etc/at.allow 文件的管理更加严格,因为只有写入这个文件的用户才能使用 at 命令,如果需要禁用 at 命令的用户较多,则可以把少数用户写入这个文件。/etc/at.deny 文件的管理较为松散,如果允许使用 at 命令的用户较多,则可以把禁用的用户写入这个文件。不过这两个文件都不能对 root 用户生效。
接下来正式介绍 at 命令。at 命令的格式非常简单,基本格式如下:
[root@localhost ~] # at [选项] [时间]
有关此命令常用的几个选项及各自含义如表 1 所示。
选项 | 含义 |
---|---|
-m | 当 at 工作完成后,无论命令是否输出,都用 E-mail 通知执行 at 命令的用户。 |
-c 工作标识号 | 显示该 at 工作的实际内容。 |
-t 时间 | 在指定时间提交工作并执行,时间格式为 [[CC]YY]MMDDhhmm。 |
-d | 删除某个工作,需要提供相应的工作标识号(ID),同 atrm 命令的作用相同。 |
-l | 列出当前所有等待运行的工作,和 atq 命令具有相同的额作用。 |
-f 脚本文件 | 指定所要提交的脚本文件。 |
另外,表 2 罗列了此命令中关于时间参数可用的以下格式。
格式 | 用法 |
---|---|
HH:MM | 比如 04:00 AM。如果时间已过,则它会在第二天的同一时间执行。 |
Midnight(midnight) | 代表 12:00 AM(也就是 00:00)。 |
Noon(noon) | 代表 12:00 PM(相当于 12:00)。 |
Teatime(teatime) | 代表 4:00 PM(相当于 16:00)。 |
英文月名 日期 年份 | 比如 January 15 2018 表示 2018 年 1 月 15 号,年份可有可无。 |
MMDDYY、MM/DD/YY、MM.DD.YY | 比如 011518 表示 2018 年 1 月 15 号。 |
now+时间 | 以 minutes、hours、days 或 weeks 为单位,例如 now+5 days 表示命令在 5 天之后的此时此刻执行。 |
at 命令只要指定正确的时间,就可以输入需要在指定时间执行的命令。这个命令可以是系统命令,也可以是 Shell 脚本。举几个例子。
【例 1】
[coot@localhost ~]# cat /root/hello.sh
#!/bin/bash
echo "hello world!!"
#该脚本会打印"hello world!!"
[root@localhost ~]# at now +2 minutes
at> /root/hello.sh >> /root/hello.log
#执行hello.sh脚本,并把输出写入/root/hello.log文件
at> <EOT>
#使用Ctrl+D快捷键保存at任务
job 8 at 2013-07-25 20:54 #这是第8个at任务,会在2013年7月25日20:54执行
[root@localhost ~]# at -c 8
#查询第8个at任务的内容
...省略部分内容...
#主要定义系统的环境变量
/root/hello.sh >> /root/hello.log
#可以看到at执行的任务
【例 2】
[root@localhost ~J# at 02:00 2013-07-26
at> /bin/sync
at> /sbin/shutdown -h now
at> <EOT>
job 9 at 2013-07-26 02:00
#在指定的时间关机。在一个at任务中是可以执行多个系统命令的
在使用系统定时任务时,不论执行的是系统命令还是 Shell 脚本,最好使用绝对路径来写命令,这样不容易报错。at 任务一旦使用 Ctrl+D
快捷键保存,实际上写入了 /var/spool/at/ 这个目录,这个目录内的文件可以直接被 atd 服务调用和执行。
表 1 中提到了 atq 命令和 atrm 命令。atq 命令用于查看当前等待运行的工作,atrm 命令后者用于删除指定的工作,它们的使用方法也很简单,这里给大家举几个简单的例子。
【例 3】atq 命令的用法。
[root@localhost ~]# atq
9 2013-07-26 02:00 a root
#说明root用户有一个at任务在2013年7月26日02:00执行,工作号是9
[root@localhost ~]# atrm [工作号]
#删除指定的at任务
【例 4】atrm 命令的用法。
[root@localhost ~]# atrm 9
[root@localhost ~]# atq
#删除9号at任务,再查询就没有at任务存在了
二十、Linux crontab命令:循环执行定时任务(详解版)
Linux 循环执行定时任务(crontab命令)
前面学习了 at 命令,此命令在指定的时间仅能执行一次任务,但在实际工作中,系统的定时任务一般是需要重复执行的。而 at 命令显然无法满足需求,这是就需要使用 crontab 命令来执行循环定时任务。
在介绍 crontab 命令之前,我们首先要介绍一下 crond,因为 crontab 命令需要 crond 服务支持。crond 是 Linux 下用来周期地执行某种任务或等待处理某些事件的一个守护进程,和 Windows 中的计划任务有些类似。
crond 服务的启动和自启动方法如下:
[root@localhost ~]# service crond restart
停止 crond: [确定]
正在启动 crond: [确定]
#重新启动crond服务
[root@localhost ~]# chkconfig crond on
#设定crond服务为开机自启动
其实,在安装完成操作系统后,默认会安装 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。
与此同时,表 1 罗列出了此命令常用的选项及功能。
选项 | 功能 |
---|---|
-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 个“*”的具体含义如表 2 所示。
项目 | 含义 | 范围 |
---|---|---|
第一个"*" | 一小时当中的第几分钟(minute) | 0~59 |
第二个"*" | 一天当中的第几小时(hour) | 0~23 |
第三个"*" | 一个月当中的第几天(day) | 1~31 |
第四个"*" | 一年当中的第几个月(month) | 1~12 |
第五个"*" | 一周当中的星期几(week) | 0~7(0和7都代表星期日) |
在时间表示中,还有一些特殊符号需要学习,如表 3 所示。
特殊符号 | 含义 |
---|---|
*(星号) | 代表任何时间。比如第一个"*"就代表一小时种每分钟都执行一次的意思。 |
,(逗号) | 代表不连续的时间。比如"0 8,12,16***命令"就代表在每天的 8 点 0 分、12 点 0 分、16 点 0 分都执行一次命令。 |
-(中杠) | 代表连续的时间范围。比如"0 5 ** 1-6命令",代表在周一到周六的凌晨 5 点 0 分执行命令。 |
/(正斜线) | 代表每隔多久执行一次。比如"*/10****命令",代表每隔 10 分钟就执行一次命令。 |
当“crontab -e”编辑完成之后,一旦保存退出,那么这个定时任务实际就会写入 /var/spool/cron/ 目录中,每个用户的定时任务用自己的用户名进行区分。而且 crontab 命令只要保存就会生效,只要 crond 服务是启动的。知道了这 5 个时间字段的含义,我们多举几个时间的例子来熟悉一下时间字段,如表 4 所示。
时间 | 含义 |
---|---|
45 22 ***命令 | 在 22 点 45 分执行命令 |
0 17 ** 1命令 | 在每周一的 17 点 0 分执行命令 |
0 5 1,15**命令 | 在每月 1 日和 15 日的凌晨 5 点 0 分执行命令 |
40 4 ** 1-5命令 | 在每周一到周五的凌晨 4 点 40 分执行命令 |
*/10 4 ***命令 | 在每天的凌晨 4 点,每隔 10 分钟执行一次命令 |
0 0 1,15 * 1命令 | 在每月 1 日和 15 日,每周一个 0 点 0 分都会执行命令,注意:星期几和几日最好不要同时出现,因为它们定义的都是天,非常容易让管理员混淆 |
现在我们已经对这 5 个时间字段非常熟悉了,可是在“执行的任务”字段中都可以写什么呢?既可以定时执行系统命令,也可以定时执行某个 Shell 脚本,这里举几个实际的例子。
【例 1】让系统每隔 5 分钟就向 /tmp/test 文件中写入一行“11”,验证一下系统定时任务是否会执行。
[root@localhost ~]# crontab -e
#进入编辑界面
*/5 * * * * /bin/echo "11" >> /tmp/test
这个任务在时间工作中没有任何意义,但是可以很简单地验证我们的定时任务是否可以正常执行。如果觉得每隔 5 分钟太长,那就换成“*”,让它每分钟执行一次。而且和 at 命令一样,如果我们定时执行的是系统命令,那么最好使用绝对路径。
【例 2】让系统在每周二的凌晨 5 点 05 分重启一次。
[root@localhost ~]# crontab -e
5.5 * * 2 /sbin/shutdown -r now
如果服务器的负载压力比较大,则建议每周重启一次,让系统状态归零。比如绝大多数游戏服务器每周维护一次,维护时最主要的工作就是重启,让系统状态归零。这时可以让我们的服务器自动来定时执行。
【例 3】在每月 1 日、10 日、15 日的凌晨 3 点 30 分都定时执行日志备份脚本 autobak.sh。
[root@localhost ~]# crontab -e
30.3 1,10,15 * * /root/sh/autobak.sh
这些定时任务保存之后,就可以在指定的时间执行了。我们可以使用命令来查看和删除定时任务,命令如下:
[root@localhost ~]# crontab -l
#查看root用户的crontab任务
*/5 * * * * /bin/echo "11" >> /tmp/test
5.5 * * 2 /sbin/shutdown -r now
30.3 1,10,15 * * /root/sh/autobak.sh
[root@localhost ~]# crontab -r
#删除root用户所有的定时任务。如果只想删除某个定时任务,则可以执行“crontab -e”命令进入
#编辑模式手工删除
[root@localhost ~]# crontab -l
no crontab for root
#删除后,再查询就没有root用户的定时任务了
在书写 crontab 定时任务时,需要注意以下几个事项:
- 6 个选项都不能为空,必须填写。如果不确定,则使用“*”代表任意时间。
- crontab 定时任务的最小有效时间是分钟,最大有效时间是月。像 2018 年某时执行、3 点 30 分 30 秒这样的时间都不能被识别。
- 在定义时间时,日期和星期最好不要在一条定时任务中出现,因为它们都以天为单位,非常容易让管理员混淆。
- 在定时任务中,不管是直接写命令,还是在脚本中写命令,最好都使用绝对路径。有时使用相对路径的命令会报错。
系统的crontab设置
“crontab -e”是每个用户都可以执行的命令,也就是说,不同的用户身份可以执行自己的定时任务。但是有些定时任务需要系统执行,这时就需要编辑 /etc/crontab 这个配置文件了。
当然,并不是说写入 /etc/crontab 配置文件中的定时任务在执行时不需要用户身份,而是“crontab -e”命令在定义定时任务时,默认用户身份是当前登录用户。而在修改 /etc/crontab 配置文件时,定时任务的执行者身份是可以手工指定的。这样定时任务的执行会更加灵活,修改起来也更加方便。
那我们打开这个文件看看吧,如下:
[root@localhost ~]# vi /etc/crontab
SHELL=/bin/bash
#标识使用哪种Shell
PATH=/sbin:/bin:/usr/sbin:/usr/bin
#指定PATH环境变量。crontab使用自己的PATH,而不使用系统默认的PATH,所以在定时任务中出现的
#命令最好使用大写
MAILTO=root
#如果有报错输出,或命令结果有输出,则会向root发送信息
HOME=/
#标识主目录
# For details see man 4 crontabs
#提示大家可以去“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 6.x 中,/etc/crontab 文件也发生了变化。在 CentOS 5.x 中,这个文件的内容大概是这样子的:
#以下输出在CentOS 5.5中
[root@sc ~]# vi /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.{daily,weekly,monthly} 目录中的所有文件。这个 run-parts 其实是一个 Shell 脚本,保存在 /usr/bin/run-parts 中,它的作用就是把其后面跟随的目录中的所有可执行文件依次执行。也就是说,如果我们想让某个脚本在每天都执行一次,那么可以不用手工去写定时任务,而只需要给这个脚本赋予执行权限,并把它放入 /etc/cron.daily/ 目录中,这样这个脚本就会在每天的凌晨 4 点 02 分执行了。
但是在 CentOS 6.x 中,/etc/crontab 文件中不再有相关的段落,那么 run-ptars 这种定时任务的执行方法是否不可用了呢?
我们看到 /etc/crontab 中有一句提示,让我们“man 4 crontabs”来查看帮助,那么我们就看看这个帮助吧!在这个帮助中,写明了“在旧版本的 crontab 配置文件中,通过 run-parts 脚本来调用 cron.{daily,weekly,monthly} 目录,定时执行这些目录中的脚本。在当前系统中,为了避免 cron 和 anacron 之间产生冲突,只要 anacron 已经安装,就使用 anacron 来执行这些目录中的脚本。具体可以查看 anacron(8) 的帮助”。对于 anacron 的用法,后续章节再详解介绍。
其实,对用户来讲,并不需要知道这个定时任务到底是由哪个程序调用的。我们需要知道的事情是如何使用系统的 crontab 设置。对此,新、老版本的 CentOS 没有区别,配置方法都有两种。
第一种方法就是把需要定时执行的工作写成脚本程序,并赋予执行权限,然后直接把这个脚本复制到 /etc/cron.{daily,weekly,monthly} 目录中的任意一个。比如,我需要让某个脚本每周执行,就把这个脚本复制到 /etc/cron.weekly/ 目录中。这样这个脚本就会每周执行一次,具体的执行时间要参考 anacron 的配置文件。
第二种方法就是修改 /etc/crontab 这个配置文件,加入自己的定时任务,不过需要注意指定脚本的执行者身份。例如:
[root@localhost ~]# vi /etc/crontab
…省略部分输出…
* * * * * root run-parts /root/cron/
#让系统每分钟都执行一次/root/cron/目录中的脚本,脚本执行者是root用户
#虽然在CentOS 6.x中不直接通过此配置文件调用/etc/cron.{daily,weekly,monthly}这些目录,但是run-parts脚本还是可以使用的。所以我完全可以参照CentOS 5.x的方法来写定时任务
#使用run-parts脚本调用并执行/root/cron/目录中所有的可执行文件
[root@localhost ~]# mkdir cron
#建立/root/cron/目录
[root@localhost cron]# vi /root/cron/hello.sh
#/bin/bash
echo "hello" >> /root/cron/hello.log
#在/root/cron/hello.log文件中写入“hello”
[root@localhost cron]# chmod 755 hello.sh
#赋予执行权限
#因为hello.sh脚本放入了/root/cron/目录中,所以每分钟执行一次。
只要保存 /etc/crontab 文件,这个定时任务就可以执行了。当然要确定 crond 服务是运行的。
这两种方法都是可以使用的,具体看个人的习惯。不过,要想修改 /etc/crontab 文件,必须是 root 用户,普通用户不能修改,只能使用用户身份的 crontab 命令。
二十一、Linux 检测长期未执行的定时任务(anacron命令)
Linux anacron命令用法详解
anacron 是用来做什么的呢?设想这样一个场景,Linux 服务器会在周末关机两天,但是设定的定时任务大多在周日早上进行,但在这个时间点,服务器又处于关机状态,导致系统很多定时任务无法运行。
又比如,我们需要在凌晨 5 点 05 分执行系统的日志备份,但 Linux 服务器不是 24 小时开机的,在晚上需要关机,白天上班之后才会再次开机,在这个定时任务的执行时间我们的服务器刚好没有开机,那么这个定时任务就不会执行了。anacron 就是用来解决这个问题的。
anacron 会以 1 天、1周(7天)、一个月作为检测周期,判断是否有定时任务在关机之后没有执行。如果有这样的任务,那么 anacron 会在特定的时间重新执行这些定时任务。
那么,anacron 是如何判断这些定时任务已经超过执行时间的呢?这就需要借助 anacron 读取的时间记录文件。anacron 会分析现在的时间与时间记录文件所记载的上次执行 anacron 的时间,将两者进行比较,如果两个时间的差值超过 anacron 的指定时间差值(一般是 1 天、7 天和一个月),就说明有定时任务没有执行,这时 anacron 会介入并执行这个漏掉的定时任务,从而保证在关机时没有执行的定时任务不会被漏掉。
在 CentOS 6.x 中,使用 cronie-anacron 软件包取代了 vixie-cron 软件包。而且在原先 CentOS 版本的 /etc/cron.{daily,weekly,monthly} 目录中的定时任务会同时被 cron 和 anacron 调用,这样非常容易出现重复执行同一个定时任务的错误。因此,在 CentOS 6.x 中,/etc/cron.{daily,weekly,monthly} 目录中的定时任务只会被 anacron 调用,从而保证这些定时任务只会在每天、每周或每月定时执行一次,而不会重复执行。
不仅如此,在 CentOS 6.x 中,anacron 还有一个变化,那就是 anacron 不再是单独的服务,而变成了系统命令。也就是说,我们不再使用“service anacron restart”命令来管理 anacron 服务了,而需要使用 anacron 命令来管理 anacron 工作。
anacron命令的基本格式如下:
[root@localhost ~]# anacron [选项] [工作名]
这里的工作名指的是依据 /etc/anacrontab 文件中定义的工作名。表 1 罗列出了此命令常用的几个选项及各自的功能。
选项 | 功能 |
---|---|
-f | 强制执行相关工作,忽略时间戳。 |
-u | 更新 /var/spool/anacron/cron.{daily,weekly,monthly} 文件中的时间戳为当前日期,但不执行任何工作。 |
-s | 依据 /etc/anacrontab 文件中设定的延迟时间顺序执行工作,在前一个工作未完成前,不会开始下一个工作。 |
-n | 立即执行 /etc/anacrontab 中所有的工作,忽略所有的延迟时间。 |
-q | 禁止将信息输出到标准错误,常和 -d 选项合用。 |
在当前的 Linux 中,其实不需要执行任何 anacron 命令,只需要配置好 /etc/anacrontab 文件,系统就会依赖这个文件中的设定来通过 anacron 执行定时任务了。那么,关键就是 /etc/anacrontab 文件的内容了。这个文件的内容如下:
[root@localhost ~]# vi /etc/anacrontab
# /etc/anacrontab: configuration file for anacron
# See anacron(8) and anacrontab(5) for details.
SHELL=/bin/sh
PATH=/sbin:/bin:/usr/sbin:/usr/bin MAILTO=root
#前面的内容和/etc/crontab类似
#the maximal random delay added to the base delay of the jobs
RANDOM_DELAY=45
#最大随机廷迟
#the jobs will be started during the following hours only
START_H0URS_RANGE=3-22
#fanacron的执行时间范围是3:00~22:00
#period in days delay in minutes job-identifier command
1 5 cron.daily nice run-parts /etc/cron.daily
#每天开机 5 分钟后就检查 /etc/cron.daily 目录内的文件是否被执行,如果今天没有被执行,那就执行
7 25 cron.weekly nice run-parts /etc/cron.weekly
#每隔 7 天开机后 25 分钟检查 /etc/cron.weekly 目录内的文件是否被执行,如果一周内没有被执行,就会执行
©monthly 45 cron.monthly nice run-parts /etc/cron.monthly
#每隔一个月开机后 45 分钟检查 /etc/cron.monthly 目录内的文件是否被执行,如果一个月内没有被执行,那就执行
在这个文件中,“RANDOM_DELAY”定义的是最大随机延迟,也就是说,cron.daily 工作如果超过 1 天没有执行,则并不会马上执行,而是先延迟强制延迟时间,再延迟随机延迟时间,之后再执行命令;“START_HOURS_RANGE”的是定义 anacron 执行时间范围,anacron 只会在这个时间范围内执行。
我们用 cron.daily 工作来说明一下 /etc/anacrontab 的执行过程:
- 读取 /var/spool/anacron/cron.daily 文件中 anacron 上一次执行的时间。
- 和当前时间比较,如果两个时间的差值超过 1 天,就执行 cron.daily 工作。
- 只能在 03:00-22:00 执行这个工作。
- 执行工作时强制延迟时间为 5 分钟,再随机延迟 0~45 分钟。
- 使用 nice 命令指定默认优先级,使用 run-parts 脚本执行 /etc/cron.daily 目录中所有的可执行文件。
大家会发现,/etc/cron.{daily,weekly,monthly} 目录中的脚本在当前的 Linux 中是被 anacron 调用的,不再依靠 cron 服务。不过,anacron 不用设置多余的配置,我们只需要把需要定时执行的脚本放入 /etc/cron.{daily,weekly,monthly} 目录中,就会每天、每周或每月执行,而且也不再需要启动 anacron 服务了。如果需要进行修改,则只需修改 /etc/anacrontab 配置文件即可。
比如,我更加习惯让定时任务在凌晨 03:00-05:00 执行,就可以进行如下修改:
[root@localhost ~] # vi /etc/anacrontab
# /etc/anacrontab: configuration file for anacron
# See anacron(8) and anacrontab(5) for details.
SHELL-/bin/sh
PATH-/sbin:/bin:/usr/sbin:/usr/bin MAILTO-root
# the maximal random delay added to the base delay of the jobs RANDOM_DELAY=0
#把最大随机廷迟改为0分钟,不再随机廷迟
# the jobs will be started during the following hours only START_HOORS_RANGE=3-5
#执行时间范围为03:00—05:00
#period in days delay in minutes job-identifier command
1 0 cron.daily nice run-parts /etc/cron.daily
7 0 cron.weekly nice run-parts /etc/cron.weekly
@monthly 0 cron.monthly nice run-parts /etc/cron.monthly
#把强制延迟也改为0分钟,不再强制廷迟
这样,所有放入 /etc/cron.{daily,weekly,monthly} 目录中的脚本都会在指定时间执行,而且也不怕服务器万一关机的情况了。
二十二、Linux 查看系统资源的使用情况(vmstat命令)
Linux vmstat命令详解:监控系统资源
如果你想动态的了解一下系统资源的使用状况,以及查看当前系统中到底是哪个环节最占用系统资源,就可以使用 vmstat 命令。
vmstat命令,是 Virtual Meomory Statistics(虚拟内存统计)的缩写,可用来监控 CPU 使用、进程状态、内存使用、虚拟内存使用、硬盘输入/输出状态等信息。此命令的基本格式有如下 2 种:
[root@localhost ~]# vmstat [-a] [刷新延时 刷新次数]
[root@localhost ~]# vmstat [选项]
-a 的含义是用 inact/active(活跃与否) 来取代 buff/cache 的内存输出信息。除此之外,表 1 罗列出了 vmstat 命令的第二种基本格式中常用的选项及各自的含义。
选项 | 含义 |
---|---|
-fs | -f:显示从启动到目前为止,系统复制(fork)的程序数,此信息是从 /proc/stat 中的 processes 字段中取得的。 -s:将从启动到目前为止,由一些事件导致的内存变化情况列表说明。 |
-S 单位 | 令输出的数据显示单位,例如用 K/M 取代 bytes 的容量。 |
-d | 列出硬盘有关读写总量的统计表。 |
-p 分区设备文件名 | 查看硬盘分区的读写情况。 |
例如:
[root@localhost proc]# vmstat 1 3
#使用vmstat检测,每隔1秒刷新一次,共刷新3次
procs ——memory—— swap —io system ——cpu——
r b swpd free buff cache si so bi bo in cs us sy id wa st
r b swpd free buff cache si so bi bo in cs us sy id wa st
0 0 0 407376 55772 84644 0 0 5 2 9 10 0 0 100 0 0
0 0 0 407368 55772 84644 0 0 0 0 12 10 0 0 100 0 0
0 0 0 407368 55772 84644 0 0 0 0 15 13 0 0 100 0 0
该命令输出信息中,各个字段以及含义如表 2 所示。
字段 | 含义 |
---|---|
procs | 进程信息字段:
|
memory | 内存信息字段:
|
swap | 交换分区信息字段:
这两个数越大,表明数据需要经常在磁盘和内存之间进行交换,系统性能越差。 |
io | 磁盘读/写信息字段:
这两个数越大,代表系统的 I/O 越繁忙。 |
system | 系统信息字段:
这两个数越大,代表系统与接口设备的通信越繁忙。 |
cpu | CPU信息字段:
|
本机是一台测试用的虚拟机,并没有多少资源被占用,所以资源占比都比较低。如果服务器上的资源占用率比较高,那么使用 vmstat 命令查看到的参数值就会比较大,我们就需要手工进行干预。如果是非正常进程占用了系统资源,则需要判断这些进程是如何产生的,不能一杀了之;如果是正常进程占用了系统资源,则说明服务器需要升级了。
二十三、Linux 查看开机信息(dmesg命令)
Linux dmesg命令:显示开机信息
通过学习《Linux启动管理》一章可以知道,在系统启动过程中,内核还会进行一次系统检测(第一次是 BIOS 进行加测),但是检测的过程不是没有显示在屏幕上,就是会快速的在屏幕上一闪而过那么,如果开机时来不及查看相关信息,我们是否可以在开机后查看呢?
答案是肯定的,使用 dmesg 命令就可以。无论是系统启动过程中,还是系统运行过程中,只要是内核产生的信息,都会被存储在系统缓冲区中,如果开机时来不及查看相关信息,可以使用 dmesg 命令将信息调出,此命令常用于查看系统的硬件信息。
除此之外,开机信息也可以通过 /var/log/ 目录中的 dmesg 文件进行查看。
dmesg 命令的用法很简单,基本格式如下:
[root@localhost ~]# dmesg
例如:
[root@localhost ~]# dmesg | grep CPU
#查看CPU的信息
Transmeta TransmetaCPU
SMP:Allowing 1 CPUs, 0 hotplug CPUs
NR_CPUS:32 nr_cpumask_bits:32 nr_cpu_ids:1 nr_node_ids:1
PERCPU:Embedded 14 pages/cpu @c1a00000 s35928 r0 d21416 u2097152
Initializing CPU#0
CPU:Physical Processor ID:0
mce:CPU supports 0 MCE banks
CPU0:Intel(R) Core(TM) i7-3630QM CPU @ 2.40GHz stepping 09
Brought up 1 CPUs
microcode:CPU0 sig=0x306a9, pf=0x1, revision=0x12
[root@localhost ~]# dmesg | grep eth0
#查看第一块网卡的信息
eth0:registered as PCnet/PCI II 79C970A
eth0:link up
eth0:no IPv6 routers present
二十四、Linux 查看内存使用状态(free命令)
Linux free命令:查看内存使用状态
free 命令用来显示系统内存状态,包括系统物理内存、虚拟内存(swap 交换分区)、共享内存和系统缓存的使用情况,其输出和 top 命令的内存部分非常相似。
free 命令的基本格式如下:
[root@localhost ~]# free [选项]
表 1 罗列出了此命令常用的选项及各自的含义。
选项 | 含义 |
-b | 以 Byte(字节)为单位,显示内存使用情况。 |
-k | 以 KB 为单位,显示内存使用情况,此选项是 free 命令的默认选项。 |
-m | 以 MB 为单位,显示内存使用情况。 |
-g | 以 GB 为单位,显示内存使用情况。 |
-t | 在输出的最终结果中,输出内存和 swap 分区的总量。 |
-o | 不显示系统缓冲区这一列。 |
-s 间隔秒数 | 根据指定的间隔时间,持续显示内存使用情况。 |
例如:
[root@localhost ~]# free -m
total used free shared buffers cached
Mem: 725 666 59 0 132 287
-/+ buffers/cache: 245 479
Swap: 996 0 996
第一行显示的是各个列的列表头信息,各自的含义如下所示:
- total 是总内存数;
- used 是已经使用的内存数;
- free 是空闲的内存数;
- shared 是多个进程共享的内存总数;
- buffers 是缓冲内存数;
- cached 是缓存内存数。
Mem 一行指的是内存的使用情况;-/buffers/cache 的内存数,相当于第一行的 used-buffers-cached。+/buffers/cache 的内存数,相当于第一行的 free+buffers+cached;Swap 一行指的就是 swap 分区的使用情况。
可以看到,系统的物理内存为 725 MB,已经使用了 666 MB,空闲 59 MB。而 swap 分区总大小为 996 MB,目前尚未使用。
二十五、Linux 查看登陆用户信息(w和who命令)
Linux w和who命令:查看登陆用户信息
Linux 中,使用 w 或 who 命令都可以查看服务器上目前已登录的用户信息,两者的区别在于,w 命令除了能知道目前已登陆的用户信息,还可以知道每个用户执行任务的情况。
首先,介绍一下 w 命令的使用,w 命令的基本格式如下:
[root@localhost ~]# w [选项] [用户名]
此命令常用选项及含义,如表 1 所示。如果 w 命令后跟 [用户名],则表示只显示此用户的信息。
选项 | 含义 |
---|---|
-h | 不显示输出信息的标题 |
-l | 用长格式输出 |
-s | 用短格式输出,不显示登陆时间,JCPU 和 PCPU 时间 |
-V | 显示版本信息 |
【例 1】显示当前用户登陆信息。
[root@localhost ~]# w
13:13:56 up 13:00, 1 user, load average: 0.08, 0.02, 0.01
USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT
root tty1 - 11:04 0.00s 0.36s 0.00s -bash
root pts/0 192.168.0.108 13:15 0.00s 0.06s 0.02s w
上面的输出信息中,第一行其实和 top 命令的第一行非常类似,主要显示了当前的系统时间、系统从启动至今已运行的时间、登陆到系统中的用户数和系统平均负载。
平均负载(load average)指的是在 1 分钟、5 分钟、15 分钟内系统的负载状况。
从第二行开始,显示的是当前所有登陆系统的用户信息,第二行是用户信息的各列标题,从第三行开始每行代表一个用户。这些标题的含义如表 2 所示。
标题 | 含义 |
---|---|
USER | 登录到系统的用户。 |
TTY | 登录终端。 |
FROM | 表示用户从哪里登陆进来,一般显示远程登陆主机的 IP 地址或者主机名。 |
LOGIN@ | 用户登陆的日期和时间。 |
IDLE | 表示某个程序上次从终端开始执行到现在所持续的时间。 |
JCPU | 和该终端连接的所有进程占用的 CPU 运算时间。这个时间里并不包括过去的后台作业时间,但是包括当前正在运行的后台作业所占用的时间。 |
PCPU | 当前进程所占用的 CPU 运算时间。 |
WHAT | 当前用户正在执行的进程名称和选项,换句话说,就是表示用户当前执行的是什么命令。 |
从 w 命令的输出中已知,Linux 服务器上已经登录了两个 root 用户,一个是从本地终端 1 登录的(tty1),另一个是从远程终端 1 登录的(pts/0),登录的来源 IP 是 192.168.0.108。
相比较 w 命令,who 命令只能显示当前登陆的用户信心,但无法知晓每个用户正在执行的命令。 who 命令的基本格式如下:
[root@localhost ~]# who [选项] [file]
需要说明的是,who 命令默认是通过 /var/run/utmp 文件来获取登陆用户信息,但如果通过 file 指定另一个文件,则 who 命令将不再默认读取 /var/run/utmp 文件,而是读取该指定文件来获取信息。
有关 who 命令常用选项及含义,如表 3 所示。
选项 | 含义 |
---|---|
-a | 列出所有信息,相当于所有选项。 |
-b | 列出系统最近启动的时间日期。 |
-l | 列出所有可登陆的终端信息。 |
-m | 仅列出关于当前终端的信息,who -m 命令等同于 who am i 。 |
-q | 列出在本地系统上的用户和用户数的清单。 |
-r | 显示当前系统的运行级别。 |
-s | 仅显示名称、线路和时间字段信息,这是 who 命令的默认选项。 |
-u | 显示当前每个用户的用户名、登陆终端、登陆时间、线路活动和进程标识。 |
-T 或 -w | 显示 tty 终端的状态,“+”表示对任何人可写,“-”表示仅对 root 用户或所有者可写,“?”表示遇到线路故障。 |
【例 2】显示系统最新启动日期,以及每个用户的登陆详情、终端状态。
[root@localhost ~]# who <--等同于 who -s
root tty1 2013-06-07 09:53
root pts/0 2013-06-07 09:53 (192.168.0.108)
#用户名 登录终端 登录时间(登录来源IP)
二十六、Linux 查看过去登陆的用户信息(last和lastlog命令)
Linux last和lastlog命令:查看过去登陆的用户信息
前面,我们已经学了使用 w 或 who 命令查看当前登陆系统的用户信息,但如果原先登录的用户现在已经退出登录,那么是否还能查看呢?当然可以,这就需要使用 last 和 lastlog 命令。
last 命令可以查看当前和过去登陆系统用户的相关信息;lastlog 命令可以查看到每个系统用户最近一次登陆系统的时间。
我们先来看看 last 命令,此命令的基本格式如下所示:
[root@localhost ~]# last [选项]
表 1 罗列出了该命令常用的选项及含义。
选项 | 含义 |
---|---|
-a | 把从何处登陆系统的主机名或 IP 地址显示在最后一行。 |
-R | 不显示登陆系统的主机名或 IP 地址。 |
-x | 显示系统关机、重新开机以及执行等级的改变等信息。 |
-n 显示列数 | 设置列出信息的显示列数。 |
-d | 将显示的 IP 地址转换成主机名称。 |
在执行 last 命令时,它默认会读取 /var/log/wtmp 日志文件,这是一个二进制文件,不能直接用 vi 编辑,只能通过 last 命令调用。
【例 1】查询当前和过去登录的用户信息。
[root@localhost ~]# last
root pts/0 192.168.0.108 Fri Jun 7 09:53 still logged in
root tty1 Fri Jun 7 09:53 still logged in
root pts/0 192.168.0.101 Fri Jun 7 06:53 - 09:52 (02:59)
root pts/1 192.168.0.103 Fri Jun 7 04:12 - 04:30 (00:18)
#用户名 登录终端 登录IP 登录时间 - 退出时间(在线时间)
reboot system boot 2.6.32-279.el6.i Thu Jun 6 23:53 - 00:03 (00:09)
#还能看到系统的重启时间
…省略部分输出…
再来看看 lastlog 命令,此命令可以查看登陆过当前系统用户的最近一次登陆时间,比如:
[root@localhost ~]#lastlog
#用户名 端口 来自 最后登陆时间
Username Port From Latest
root pts/1 192.168.1.100 Wed Mar 4 11:04:22 +0800 2009
bin **Never logged in**
....(中间省略)....
vbird1 pts/2 192.168.1.100 Wed Mar 4 13:15:56 +0800 2009
....(以下省略)....
lastlog 命令默认是去读取 /var/log/lastlog 日志文件的,这个文件同样是二进制文件,不能直接用 vi 编辑,需要使用 lastlog 命令调用。