Linux 基础学习篇 - Mandrake 9

第十五章、例行性命令的创建 - for Mandrake 9

鸟哥的第一本书籍的主要内容,内容稍微与书籍不太一样了!

最近更新时间: 2002/05/30

鸟哥的第一本书大约是在 2002 年的年底左右出版的,内容几乎都是 Linux 基础学习,一点也没有谈到服务器的部份!这也是后来的雏型! 不过内容错误的地方很多,导致在 2003 年的年底推出了『基础学习篇增订版』的内容,大致上就是处理掉一些比较有严重错误的部份。 不过,因为 Linux 的版本变化非常快速,因此,写完了这些文档之后,鸟哥还是持续在网站上更新文档内容,导致原本书籍内容的数据与网站数据差异太大! 这个问题直到鸟哥在 2008 年左右才发现!糟糕了!旧版的文档数据已经遗失~觉得相当扼腕~

因此,在底下的文档内容与当初的书籍内容虽然大同小异,不过章节的编排却是有所不同!再花时间去一个一个处理,似乎也不太符合成本效益! 鸟哥仅是想要将自己以前的文档记录下来而已,同时将过时的 big5 编码改回 utf8 编码,再加上可以支持 RWD 的样式而已啦! 内容已经不多做编排~因此,如果内容文档你看不懂,那也是应该的! ^_^

建议您前往本站查找最新版本的 Linux distribution 文章来阅读,比较不会浪费时间。最新文章请前往鸟站首页查阅啰!

什么是例行性命令?

每个人或多或少都有一些约会或者是工作,有的工作是例行性的,例如每年一次的加薪、每个月一次的工作报告、每周一次的午餐会报、每天需要的打卡等等;有的工作则是临时发生的,例如刚好总公司有高官来访,需要你准备演讲器材等等!用在生活上面,例如每年的爱人的生日、每天的起床时间等等、还有突发性的电脑大降价(阿~我等好久了~~)等等啰。这些工作都可以称为例行性命令,而这些工作 Linux 也都可以帮您提醒,例如:每一天早上 8:00 钟要服务器连接上音响,并启动音乐来唤你起床;而中午 12:00 希望 Linux 可以发一封信到你的邮件信箱,提醒你可以去吃午餐了;另外,在每年的你爱人的生日的前一天,先发封信提醒你,以免忘记这么重要的一天。
从上面的说明当中可以很清楚的发现两种工作调度的方式:
  • 一种是例行性的,就是每隔一定的周期要来办的事项;
  • 一种是突发性的,就是这次做完以后就没有的那一种(电脑大降价....)
那么在 Linux 底下如何达到这两个功能呢?呵呵!那就得使用 at 与 crontab 这两个好东西啰!
  • at : 这个工作仅运行一次就从 Linux 系统中的调度中取消;
  • crontab : 这个工作将持续例行性的作下去!
底下我们先来谈一谈 Linux 的系统到底在做什么事情,怎么有若干多的工作调度在工作呢?然后再回来谈一谈 at 与 crontab 这两个好东西!

Linux 系统的例行性命令有哪些

好了,那么服务器自己有什么例行性命令要来作呀!?Linux 的工作可多着呢!由前面提到的几篇文章中,我们知道Linux 本身在背景下的工作可是很多的,尤其是网络开放的情况下,创建与取消连接、MySQL 数据库的即时更新、以及一些例行的系统指令,例如释放内存的工作等等。由于例行的工作非常的多,实在不可能每天都要管理员来手动输入吧!所以才会创建这个工作调度的需求的!基本缺省的工作有底下这些:
  • 进行数据轮替 ( log rotate ):这个步骤重要了!尤其是在 log file 的选项当中!由于注册表案会越来越大,所以需要适时适量的将注册表备份,并以新开的文件来进行记录,这样效率会比较好,因此就需要使用 log rotate 啦!系统缺省的重要工作之一;
  • rpm 数据库的创建:虽然 RPM 数据库会在你以 RPM 安装之后即更新到 RPM 数据库当中去,但是难保会有漏网之鱼,所以系统也会设置每隔依段时间自动的搜集系统上面的 RPM 数据库来建置一番;
  • 创建 locate 的数据库:是否还记得为何使用 locate 这个指令时,搜索速度超快!那是因为 Linux 系统上将文件与路径都记录在数据库里面了!所以使用 locate 的时候,嘿嘿!直接指向数据库去 ( /var/lib/slocate/slocate.db ) ,偏偏麻烦的是这个文件的更新是每天一次!所以当你今天更新的文件,使用 locate 反而可能会找不到....
  • 进行进程的分析:每隔依段时间会进行进程的分析,如果发现有僵尸进程的时候,就会将他删去!以保持内存的工作能力!
  • 注册表视察:这个东西是在 Red Hat 7.1 以后才出现的东西,后来太好用了,所以被拿到旧版的 Red Hat 里面去使用!基本上就是分析注册表啦!然后据以解析有问题的纪录档,以维护主机的安全性!这部份不才小弟也自己写了一个简易型的分析文件,觉得更好用就是了!
  • 指纹数据库的比对:基本上就是 tripwire 这个套件啦!可以用来分析最近被更动过的文件内容!蛮不错的一个程序!有空也来玩玩看。
Linux 缺省的例行工作至少就有这些了,再加上您努力的为 Linux 进行工作调度的设计,嘿嘿!每天的工作量可是相当的大的呢!

仅运行一次的工作调度

如果仅要运行一次的工作,就使用 at 这个指令吧!这个指令其实就是 atd 这个服务啦!所以请记得一定要启动这个服务呦!如果是在 Red Hat 系统下,可以使用:
  1. ntsysv
  2. 选择 atd
  3. 按下 OK !
如果是在 Mandrake 系统下,可以使用:
  1. chkconfig --add atd
  2. chkconfig --list

  3. 上面这个指令可以查看 atd 在 run-level 正确的情况中,是否会在开机的时候被启动!
基本上, atd 是缺省打开的,如果您没有更动过系统默认值的话,那么上面的动作就不需要动啰!下达 at 这个动作会将工作调度写入 /var/spool/at 这个目录下呢!然后等待系统将之运行啰!此外,这个 at 指令虽然缺省是所有人都能进行,但是可以经由 root 的规范来限制使用的人口。限制的方法其实与 /etc/hosts.allow(deny) 类似,使用 /etc/at.allow(deny) 这两个文件来限制:
  • 限制用户原理:当用户运行 at 时,系统会

  •  
    1. 先找寻 /etc/at.allow 这个文件,写在这个文件中的用户才能使用 at ,没有在这个文件中的用户则不能使用 at ( 即使没有写在 at.deny 当中  );
    2. 如果没有 /etc/at.allow 就寻找 /etc/at.deny 这个文件,若写在这个 at.deny 的用户则不能使用 at ,而没有在这个 at.deny 文件中的用户,就可以使用 at 咯;
    3. 如果两个文件都不存在,那么只有 root 可以使用 at 这个指令。
  • Linux 缺省情况下,只有 /etc/at.deny 这个文件,且这个文件的内容为空白的,由于内容没有任何用户,所以当然『所有人都可以使用 at 』
  • 如果不想要某个用户使用 at 时,那么将该用户帐号写到 /etc/at.deny 这个文件中即可。
好了!我们来谈一谈 at 的语法吧!
 
[test @test test]# at [-m] TIME    (下达工作指令)
[test @test test]# atq         (查看目前的工作调度)
[test @test test]# atrm [jobnumber]  (删除调度)
参数说明:
-m    :运行 at 所规范的工作调度时,将屏幕输出结果 mail 给下达指令的用户
TIME  :时间的格式,有底下几个:
   HH:MM YYYY-MM-DD             ex> 04:00 2002-05-30 (五月三十号四点运行)
   HH[pm;am] + number [hours;days;weeks]  ex> 4pm + 3 days (在过 3 天的下午 4 点)
   HH:MM                  ex> 12:00 (今天的 12 点运行)
   HH[pm;am] [Month] [Day]         ex> 1pm May 30
jobnumber:每一个 at 工作调度都有编排的顺序!这个即是!
范例:

[test @test test]# at 5pm   <==在今天的 5pm 运行,如果今天已过 5 点则明天运行;
warning: commands will be executed using (in order) a) $SHELL b) login shell c) /bin/sh
at> mail -s test test < /home/test/.bashrc <==这就是我的工作!
at> <EOT> <==这里是按下 [Ctrl] + D 就可以离开了!
job 8 at 2002-05-30 17:00  <==这里会告诉你这个工作的号码为 8 号,运行的日期为后面所示。

[test @test test]# atq   <==窥视一下你(test)目前有多少工作?
5       2002-05-30 12:00 a test
8       2002-05-30 17:00 a rest

[test @test test]# atrm 5<==删除第 5 号工作
[test @test test]# atq
8       2002-05-30 17:00 a rest

请注意!在 at 下达之后,便进入指令列下达的模式!在这里你可以重复的输入指令,但是离开的时候请下达『 [Ctrl] + D 』就可以离开了!离开之后,系统会告诉你这个工作调度的号码与用户是谁!呵呵!很简单吧!

循环运行的例行性命令

这个循环的例行性命令其实就是 cron 这个服务啦 (crond)!当你下达 crontab 的指令之后,会将你的命令写入 /var/spool/cron这个目录当中呦!例如 test 下达了他的 crontab 命令,那么就会自动产生 /var/spool/cron/test 这个文件!『但请注意,这个文件不能直接编辑!』然后运行的指令记录会放置在 /var/log/cron 这个文件中!所以,『如果您的 Linux 系统不知道是否被木马入侵时,可以搜索一下 /var/log/cron 这个记录挡,视察看看有没有被搞鬼?』
好了!我们来看一下 crontab 的指令语法吧!
 
[test @test test]# crontab [-u user] [-l | -e | -r]
参数说明:
-u user :只有 root 能下达的参数,视察或编译其他用户的 crontab 内容
-l      :列出 crontab 的内容
-e      :编辑 crontab 的内容
-r      :删除 crontab 的内容
范例:
一般用户 test 要在每天的 12:00 发信给自己:

[test @test test]# crontab -e <==自己编辑自己的 crontab 内容

进入 crontab 编辑内容,使用 vi 呦!

0 12 * * * mail test < /home/test/test.txt
分时日月周 |========指令列===============|

上面的例子是说:假如你需要在每天的正午 12:00 发一封信给你自己,而且信的内容已经写好了,那要怎样作呢?而且,另一个假设是,你在 Linux Server 中的权限仅止于一般用户,并不是 root (管理员)身份,那要怎样设置你的例行性命令呢?哈哈!那就使用 crontab 这个指令吧!你只要运行『 crontab -e 』就可以进入 vi 的编辑画面来编辑你的例行性命令说!

在上面的例子中,输入 crontab -e 时,会出现一个 vi 画面,然后你在 vi 画面中输入上面的一行字,之后按 :wq 保存后离开!即可完成编辑!容易吧!那上面那一行字代表什么意义呢?你可以看到,在真正运行命令之前(就是 mail test < /home/test/test.txt )总共有五个数字,这五个数字分别代表:
分  (0-59)
小时 (0-23)
日期 (1-31)
月份 (1-12)
周  (0-6)
数字代表的意义
分钟
小时
日期
月份
范围
0-59
0-23
1-31
1-12
0-6 (0为星期天)
另外,如果是『 *  』的时候,代表所有数字都适用的意思。所以,你就可以知道我上面那一行写的意义为何了!那就是『不论何月、何日、星期几的 12 点 0 分时,运行 mail test < /home/test/test.txt 这个命令』!还不了解?没关系,我们这里作几个例子!
 
例题一:假如你的女朋友生日是 5 月 2 日,你想要在 5 月 1 日的 23:59 发一封信给他,
    这封信的内容已经写在 /home/test/lover.txt 中了

[test @test test]# crontab -e

59 23 1 5 * mail pigpp < /home/test/lover.txt

那样的话,每年 pigpp 都会收到你的这封信喔!(当然啰,信的内容就要每年变一变啦!)
 
例题二:假如你每隔五分钟要去 check 你的一个名为 test.sh 的批量档一次,则:

[test @test test]# crontab -e

59 23 1 5 * mail pigpp < /home/test/lover.txt  <==刚刚的那个指令还存在呦!
*/5 * * * * /home/test/test.sh  <==新加入的一个调度!

注意到呦!那个 crontab 每个人都只有一个文件,就是在 /var/spool/cron 里面的文件啦!还有两件事要注意一下:
(1) 指令的路径最好是下达绝对路径,这样比较不会找不到运行的文件喔;
(2) 第一个数字 */5 表示『每五分钟运行一次』的意思!
例题三:假如你每个礼拜的星期五下午 4:30 要告诉朋友星期六的约会不要忘记,则:

[test @test test]# crontab -e

59 23 1 5 * mail pigpp < /home/test/lover.txt 
*/5 * * * * /home/test/test.sh
30 16 * * 5 mail frend@test.domain.name < /home/test/frend.txt <==新加入的!

呵呵!这样很简单吧!如此就可以轻易的达到您所需要的例行性工作调度的安排啰!
好了!那么我们要如何来查看用户目前的 crontab 的工作调度呢?
 
[test @test test]# crontab -l <==这个 -l 是 L 的小写
# DO NOT EDIT THIS FILE - edit the master and reinstall.
# (/tmp/crontab.27683 installed on Thu May 30 13:38:38 2002)
# (Cron version -- $Id: crontab.c,v 2.13 1994/01/17 03:20:37 vixie Exp $)
59 23 1 5 * mail pigpp < /home/test/lover.txt
*/5 * * * * /home/test/test.sh
30 16 * * 5 mail frend@test.domain.name < /home/test/frend.txt
呵呵呵!其实这个显示的内容就是 /var/spool/cron/test 文件的内容啦!那么如何删除调度呢?
 
[test @test test]# crontab -r
[test @test test]# crontab -l
no crontab for test
看到了吗? crontab 『整个内容都不见了!』所以请注意:『如果只是要删除某个 crontab 的工作项目,那么请使用 crontab -e 来重新编辑即可!』如果使用 -r 的参数,是会将所有的 crontab 数据内容都删掉的!千万注意了!

系统的 crontab 设置

这个『 crontab -e 』是针对用户的 cron 来设计的,如果是『系统的例行性任务』时,该怎么办呢?是否还是需要以 crontab -e 来管理你的例行性命令呢?当然不需要,你只要编辑 /etc/crontab这个文件就可以啦!有一点需要特别注意喔!那就是 crontab -e 这个 crontab 其实是 /usr/bin/crontab 这个运行档,但是 /etc/crontab 可是一个『纯文本档』喔!你可以 root 的身份编辑一下这个文件哩!
基本上, cron 这个服务的最低侦测限制是『分钟』,所以『 cron 会每分钟去读取一次 /etc/crontab 与 /var/spool/cron 里面的数据内容』,因此,只要你编辑完 /etc/crontab 这个文件,并且将他保存之后,呵呵!那么 crontab 的设置就自动的会来运行了!
注意:在 Linux 底下的 crontab 会自动的帮我们每分钟重新读取一次 /etc/crontab 的例行工作事项,但是某些原因或者是其他的 Unix 系统中,由于 crontab 是读到内存当中的,所以在你修改完 /etc/crontab 之后,可能并不会马上运行,这个时候请重新启动 crond 这个服务吧!
/etc/rc.d/init.d/crond restart
好了,我们来看看 /etc/crontab 这的文件的内容吧:
 
[root@test /root]# 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  <==每个月运行的工作
分 时日月周 用户    参数     指令

看到这个文件的内容你大概就了解了吧!呵呵,没错!这个文件与将刚刚我们下达 crontab -e 的内容几乎完全一模一样!只是有几个地方不太相同:
    • MAILTO=root:是说,当 /etc/crontab 这个文件中的例行性命令发生错误时,会将错误消息或者是屏幕显示的消息传给谁?由于 root 并无法在用户端中收信,因此,我通常都将这个 e-mail 改成自己的帐号,好让我随时了解系统的状况!
    • 01 * * * * root run-parts /etc/cron.hourly:在注解符号 #run-parts 这一行以后的命令,我们可以发现,五个数字后面接的是 root 喔!没错,这一行代表的是『运行的层级为 root 身份』当然啰,你也可以将这一行改写成其他的身份哩!而 run-parts 代表后面接的 /etc/cron.hourly 是『一个目录内(/etc/cron.hourly)的所有可运行档』,这也就是说,个小时的 01 分,系统会以 root 层级的用户去 /etc/cron.hourly 这个目录下运行所有可以运行的文件!后面的三行也都是类似的意思!你可以到 /etc/ 底下去看看,系统本来就缺省了这四个目录了!你可以将每天需要运行的命令直接写到 /etc/cron.daily 即可,还不需要使用到 crontab -e 的程序呢!方便吧!
        注意:基本上 /etc/crontab 里头支持两种下达指令的方式,一种是直接以 指令型态 下达,一种则是以『目录规划』来下达;
        • 指令型态

        • 01 * * * * test mail -s test test < /home/test/test.txt
          用户是 test, 且在每个小时运行一次指令 mail ...
        • 目录规划

        • */5 * * * * root run-parts /root/runcron
          创建一个 /root/runcron 的目录,将要每隔五分钟运行的『可运行档』都写到该目录下,就可以让系统每五分钟运行一次该目录下的所有可运行档。
    这样就可以晓得 run-parts 的用意了吧!此外,与 crontab -e 规划当中最不相同的就是多了一个『用户层级』的概念,通常我们都是以 root 的角度来规划例行性命令,但是总有不需要 root 的指令吧!就可以使用这个层级来规范该进程的用户属于谁啰!
    好!你现在大概了解了这一个咚咚吧!OK!假设你现在要作一个目录,让系统可以每 2 分钟去运行这个目录下的所有可以运行的文件,你可以写下如下的这一行在 /etc/crontab 中:
      */2 * * * * root run-parts /etc/cron.min
    当然啰, /etc/cron.min 这个目录是需要存在的喔!那如果我需要运行的是一个『程序』而已,不需要用到一个目录呢?该如何是好?例如在侦测网络流量时,我们希望每五分钟侦测分析一次,可以这样写:
      */5 * * * * root /usr/local/mrtg-2/bin/mrtg /usr/local/apache/htdocs/mrtg/net/mrtg.cfg
    没有了 run-parts 就是代表『一个文件』的意思啦!
    如何!?创建例行性命令很简单吧!如果你是系统管理员的话,直接修改 /etc/crontab 这个文件即可喔!又便利,又方便管理呢!

安全的防护

  • 资源分配不均

  • 当大量使用 crontab 的时候,总是会有问题发生的,最严重的问题就是『系统资源分配不均』的问题,以我的系统为例, VBird 有侦测流量的信息,包括:
    • 流量
    • 区域内其他 PC 的流量侦测
    • CPU 使用率
    • RAM 使用率
    • 在线人数即时侦测
    如果每个流程都在同一个时间启动的话,呵呵!那么在某个时段时,我的系统会变的相当的繁忙,所以,这个时候就必须要分别设置啦!我可以这样做:
     
    [root@test /root]# vi /etc/crontab
    1,6,11,16,21,26,31,36,41,46,51,56 * * * * root ........  <==那个 .. 代表你的指令
    2,7,12,17,22,27,32,37,42,47,52,57 * * * * root ........
    3,8,13,18,23,28,33,38,43,48,53,58 * * * * root ........
    4,9,14,19,24,29,34,39,44,49,54,59 * * * * root ........
    看到了没?那个『 , 』分隔的时候,请注意,不要有空白字符!(连续的意思)如此一来,则可以将每五分钟工作的流程分别在不同的时刻来工作!则可以让系统的运行较为顺畅呦!
  • 取消不要的输出项目

  • 另外一个困扰发生在『当有运行成果或者是运行的项目中有输出的数据时,该数据将会 mail 给 MAILTO 设置的帐号』,好啦,那么当有一个调度一直出错(例如 DNS 的侦测系统当中,若 DNS 上层主机挂掉,那么你就会一直收到错误消息!)怎么办?呵呵!还记得 BASH 与 Shell scripts 那一章吧!?直接以『命令重导向』将输出的结果输出到 /dev/null 这个垃圾桶当中就好了!
  • 安全的检验

  • 很多时候被植入木马都是以例行命令的方式植入的,所以可以借由检查 /var/log/cron 的内容来视察是否有『非您设置的 cron 被运行了?』这个时候就需要小心一点啰!

本章习题练习 ( 要看答案请将鼠标移动到『答:』底下的空白处,按下左键圈选空白处即可察看)

  • 今天假设我有一个指令程序,名称为: ping.sh 这个文件名!我想要让系统每三分钟运行这个文件一次,但是偏偏这个文件会有很多的消息显示出来,所以我的 root 帐号每天都会收到差不多四百多封的信件,光是收信就差不多快要疯掉了!那么请问应该怎么设置比较好呢?

  • 答:
      这个涉及命令重导向的问题,我们可以将他导入文件或者直接丢弃!如果该消息不重要的话,那么就予以丢弃,如果消息很重要的话,才将他保留下来!假设今天这个命令不重要,所以将他丢弃掉!因此,可以这样写:
      */5 * * * * root /usr/local/ping.sh > /dev/null 2>&1
修改历史:
  • 2002/05/30:第一次完成
  • 2003/02/10:重新编排与加入 FAQ
其他链接
环境工程模式篇
鸟园讨论区
鸟哥旧站

今日 人数统计
昨日 人数统计
本月 人数统计
上月 人数统计