Linux 基础学习篇 - Fedora Core 4

第十七章、进程与资源管理 - for Fedora Core 4

进程与资源管理

最近更新时间: 2005/09/18

本文数据主要针对 Fedora Core 4 的系统进行说明, Fedora Core 1 主要是由 Red Hat Linux 9 改版而来, 这个 Red Hat Linux 9 并不是当前大家听到的 RHEL 喔!那是在 RHEL 出现之前的产品,基本上是在 2003 年以前的作品了!Fedora Core 4 则是在 2005 年 6 月份发布,使用的内核是 2.6.11 版,当时是很红的一个作品!只是生命周期太短,所以用这个 Fedora 系列来介绍 Server, 当时的决定确实有点莫名其妙了...

建议您前往本站查找最新版本的 Linux distribution 文章来阅读,比较不会浪费时间。那为何还需要编辑 Fedora Core 4 的数据呢? 鸟哥只想要做个自己曾经撰写过的文档内容保存而已啰! ^_^!最新文章请前往鸟站首页查阅啰!

在 Linux 当中, Linux 是如何分辨一个进程的呢?嗯!当我们的系统里面有太多的死亡的进程的时候, 应该怎样将该进程查出来之后并杀掉他呢?如果主机仅允许一次登录一个终端机画面, 如何从事多个工作的进行呢?还有,如何设置一个进程,让他的运行顺序可以比较快速呢?! 这个都是进程控制的重点项目呦!呵呵!另外一个又更常发生啦!如果我的 X-Window 死掉了!但是我的 Linux 基本上却还是活着的时候,那么是否需要重新 reboot 呢?还是有其他的方式可以重新启动 X-Window ? 仔细瞧一瞧整个 process 的概念喔!

什么是进程 (process)

由前面一连几个章节的数据看来,我们一直强调在 Linux 底下所有的指令与您能够进行的动作都与权限有关, 而系统如何判定你的权限呢?当然就是前面 帐号管理 章节当中提到的 UID/GID 的相关概念,以及文件的属性相关性啰!再进一步来解释, 您现在大概知道,在 Linux 系统当中:『触发任何一个事件时, 系统都会将他定义成为一个进程,并且给予这个进程一个 ID ,称为 PID,同时依据启发这个进程的用户与相关属性关系, 给予这个 PID 一组有效的权限设置。』 从此以后,这个 PID 能够在系统上面进行的动作,就与这个 PID 的权限有关了!

看这个定义似乎没有什么很奇怪的地方,不过,您得要了解什么叫做『触发事件』才行啊! 我们在什么情况下会触发一个事件?而同一个事件可否被触发多次?呵呵!来了解了解先!

进程与运行档 (process & program)

我们如何产生一个 Process ID (PID) 呢?其实很简单啦,就是『运行一个程序或指令』 就可以触发一个事件了而取得一个 PID 啰!我们说过,系统应该是仅认识 binary file 的, 那么当我们要让系统工作的时候,当然就是需要启动一个 binary file 啰, 那个 binary file 就是程序 (program) 啦!

那我们知道,每个程序都有三组人马的权限,每组人马都具有 r/w/x 的权限, 所以:『不同的用户身份运行这个 program 时,系统给予的权限也都不相同!』 举例来说,我们可以利用 touch 来创建一个空的文件,当 root 运行这个 touch 指令时,他取得的是 UID/GID = 0/0 的权限,而当 dmtsai (UID/GID=501/501) 运行这个 touch 时,他的权限就跟 root 不同啦!

再举个更常见的例子,我们要操作系统的时候,通常是利用连接程序或者直接在主机前面登录, 然后取得我们的 shell 对吧!那么,我们的 shell 是 bash 对吧,这个 bash 在 /bin/bash 对吧, 那么同时间的每个人登录都是运行 /bin/bash 对吧!不过,每个人取得的权限就是不同! 也就是说,我们可以这样看:
程序与进程之间的差异
图一、程序与进程之间的差异

也就是说,当我们登录并运行 bash 时,系统已经给我们一个 PID 了, 这个 PID 就是依据登录者的 UID/GID (/etc/passwd) 来的啦~ 以上面的图来做说明的话,我们知道 /bin/bash 是一个程序 (program),当 dmtsai 登录后,他取得一个 PID 号码为 2234 的进程,这个进程的 User/Group 都是 dmtsai, 而当这个程序进行其他作业时,例如上面提到的 touch 这个指令时, 那么由这个进程衍生出来的其他进程在一般状态下,也会沿用这个进程的相关权限的!


  • 子进程与父进程:
  • 在上面的说明里面,我们有提到所谓的『衍生出来的进程』,那是个啥咚咚? 这样说好了,当我们登录系统后,会取得一个 bash 的 shell ,然后,我们用这个 bash 提供的接口去运行另一个指令,例如 /usr/bin/passwd 或者是 touch 等等, 那些另外运行的指令也会被触发成为 PID ,呵呵!那个 PID 就是『子进程』了, 而在我们的 bash 环境下,就称为『父进程』了!

    另外,是否还记得我们在 bash shell 那一篇里面有提到 『环境变量』在不同进程之间的调用呢?现在稍微晓得是什么意思了吗? 是啦!因为我们有运行不同的 bash 嘛!既然运行两次,自然就会取得两个 PID, 而因为要让两个 PID 之间具有一些相关性,我们的 bash 就使用了环境变量啰!

    例题:请在目前的 bash 环境下,再触发一次 bash ,并以『 ps -l 』这个指令观察进程相关的输出信息。
    答:
      直接运行 bash ,会进入到子进程的环境中,然后输入 ps -l 后,出现:
      F S   UID   PID  PPID  C PRI  NI ADDR SZ WCHAN  TTY          TIME CMD
      0 S   500 21337 21336  0  75   0 -  1348 wait   pts/1    00:00:00 bash
      0 S   500 22573 21337  2  75   0 -  1348 wait   pts/1    00:00:00 bash
      0 R   500 22591 22573  0  76   0 -  1302 -      pts/1    00:00:00 ps
      有看到那个 PID 与 PPID 吗?第一个 bash 的 PID 与第二个 bash 的 PPID 都是 21337 啊, 因为第二个 bash 是来自于第一个所产生的嘛!

    重点来啦!所以说,在系统上面的各个进程可能是有相关性的喔! 也就是有所谓的父进程与子进程的关系~至于进程的相关性,我们可以使用 pstree 这支程序去查验, 就能知道彼此之间的关系了。

    另外要注意的是:所谓『擒贼先擒王』, 如果哪天你一直发现『奇怪,怎么有个程序关闭后,不久又会自动产生? 而且自动产生的 PID 还不一样!』,呵呵!大概不需要怀疑的是,如果不是 例行性命令 的影响, 肯定有一支父进程存在,他会一直重新触发你想要关闭的那个进程, 导致你老是关不了。那怎么办?不是说过擒贼先擒王吗?关闭那支父进程啦! ^_^

    其实子进程与父进程之间的关系还挺复杂的,最大的复杂点在于程序互相之间的调用, 以及两者权限的相关性!这个可能就得要您自己多多创建自己的经验了~


  • 系统或网络服务:常驻在内存的进程
  • 如果就我们之前学到的一些指令数据来看,其实我们下达的指令都很简单, 包括用 ls 显示文件啊、用 touch 创建文件啊、rm/mkdir/cp/mv 等指令管理文件啊、 chmod/chown/passwd 等等的指令来管理权限等等的,不过,这些指令都是运行完就结束了。 也就是说,该项指令被触发后所产生的 PID 很快就会终止呢! 那有没有一直在运行的进程啊?当然有啊!而且多的是呢!

    举个简单的例子来说好了,我们知道系统每分钟都会去扫瞄 /etc/crontab 以及相关的设置档, 来进行工作调度吧?那么那个工作调度是谁负责的?当然不是鸟哥啊! 呵呵!是 crond 这个程序所管理的,我们将他启动在背景当中一直持续不断的运作, 套句以前 DOS 年代常常说的一句话,那就是『常驻在内存当中的进程』啦!

    这些常驻在内存当中的进程有很多,不过主要大致分成系统本身所需要的服务, 例如刚刚提到的 crond 及 atd ,还有 syslog 等等的。还有一些则是负责网络连接的服务, 例如 Apache, named, postfix, vsftpd... 等等的。这些网络服务比较有趣的地方, 在于这些程序被运行后,他会启动一个可以负责网络监听的端口口 (port) , 以提供外部用户端 (client) 的连接要求。

    这部分我们会在认识系统服务的地方再好好的讲一讲, 在这里,您先有个概念,大概知道一下,系统上面的 PID 几乎都是通过运行一些指令所产生的, 而这些指令可能会负责一些重要的工作,例如网络服务器啊、系统性能维持啊、 或是其他系统重要工作等等。若有兴趣的话,可以先以 netstat 检查一下您主机上的网络服务喔!

    Linux 的多人多任务环境

    我们现在知道了,其实在 Linux 底下运行一个指令时,系统会给予这个动作一个 ID, 我们称为 PID,而根据激活这个指令的用户与相关的指令功能,而给予这个特定 PID 一组权限, 该指令可以进行的行为则与这个 PID 的权限有关。根据这个说明,我们就可以简单的了解, 为什么 Linux 这么多用户,但是却每个人都可以拥有自己的环境了吧!^_^

  • 多人环境:
  • Linux 最棒的地方就在于他的多人多任务环境了!那么,什么是『多人多任务』?!在 Linux 上面允许不同的人使用,而且每个人都有其特殊的权限,只有一个人具有至高无上的权力,那就是 root (系统管理员),除了他之外,其他人都必须要受一些限制的!而每个人进入 Linux 的环境设置都可以随着每个人的喜好来设置 (还记得我们在 BASH 那一章提过的 ~/.bashrc 吧!?对了!就是那个光!)!现在知道为什么了吧? 因为每个人登录后取得的 shell 的 PID 不同嘛!

  • 多任务行为:
  • 我想,在某些其他操作系统中,您可能会遇到这样的事情:『这个文件正在使用中, 您无法打开这个文件!』我哩勒!还得将正在运行当中的程序关掉之后才能开这个中间暂存盘!! 而且这个时候还只有我自己一个人在使用呢~受不了~呵呵!不过, Linux 就不会这样啰!您可以同时在不同的画面,同时由不同的人 (当然啰,有的是经由 SSH 网络连接过来,有的是直接在屏幕前面的朋友啰!)使用『同一个文件』, 不论是打开或者是修改,只要您有权限,就可以使用该文件!!

    这个东西可有用的紧!由于鸟哥是很常使用程序的 (就是 Fortran 啦,吃饭的工具!) ,而由于我们有一部主机专门用来工作的,所以配备比较高档一点 PIII 的双 CPU ),那么我就可以同时的进行两个 compiler 的进程,而且还不会互相的影响, 并且资源分配的还蛮均匀的!哈哈!怎么会跑得这么顺畅呀!爽毙了!

    其实操作系统的多任务是很复杂的行为啦!尤其涉及将多个工作直接丢给一颗 CPU 来处理~ 现在我们应该比较清楚的是,所谓的『工作』其实是将多个指令触发成为系统进程 (PID), 而这些进程若同时被触发时,那么一颗 CPU 就得要同时负责许多任务作了。 但我们晓得的是,并非每个进程都很耗系统资源,例如前一节提到的 crond 与 atd 这两个系统服务, 他们并没有消耗很多系统资源的。此时,当然啰, CPU 就可以进行其他工作, 这就是所谓的多任务!

  • 多重登录环境的七个基本终端窗口:
  • 在 Linux 当中,缺省提供了六个文本界面登录窗口,以及一个图形界面,你可以使用 [Alt]+[F1].....[F7] 来切换不同的终端机界面,而且每个终端机界面的登录者还可以不同人! 很炫吧!这个东西可就很有用啦!尤其是在某个进程死掉的时候!

    其实,这也是多任务环境下所产生的一个情况啦! 我们的 Linux 缺省会启动六个终端机登录环境的程序,所以我们就会有六个终端机接口。 您也可以减少啊!就是减少启动的终端机程序就好了。详细的数据可以先查阅 /etc/inittab 这个文件,未来我们在开机管理流程会再仔细的介绍的!

  • 特殊的进程管理行为:
  • 以前的鸟哥笨笨的,总是以为使用 Windows 98 就可以啦!后来,因为工作的关系,需要使用 Unix 系统,想说我只要在工作机前面就好, 才不要跑来跑去的到 Unix 工作站前面去呢!所以就使用 Windows 连到我的 Unix 工作站工作!

    好死不死,我一个进程跑下来要 2~3 天,唉~偏偏常常到了第 2.5 天的时候, Windows 98 就给他挂点去!当初真的是给他怕死了~后来因为换了新电脑,用了随机版的 Windows 2000 ,呵呵,这东西真不错 (指对单人而言) ,在当机的时候, 他可以仅将错误的进程踢掉,而不干扰其他的进程进行,呵呵! 从此以后,就不用担心会当机连连啰!不过,2000 毕竟还不够好,因为有的时候还是会死当!!

    那么 Linux 呢?哈哈!更棒了,几乎可以说绝对不会当机的!因为他可以在任何时候, 将某个被困住的进程杀掉,然后在重新运行该进程而不用重新开机!够炫吧!那么如果我在 Linux 下以文本界面登录,在屏幕当中显示错误消息后就挂了~动都不能动,该如何是好!? 这个时候那缺省的七个窗口就帮上忙啦!你可以随意的再按  [Alt]+[F1].....[F7] 来切换到其他的终端机界面,然后以 ps -aux 找出刚刚的错误进程,然后给他 kill 一下,哈哈,回到刚刚的终端机界面!恩~棒!又回复正常啰!

    为什么可以这样做呢?我们刚刚不是提过吗?每个进程之间可能是独立的,也可能有相依性, 只要到独立的进程当中,删除有问题的那个进程,当然他就可以被系统移除掉啦!^_^

  • bash 环境下的工作管理 (job control)
  • 我们在上一个小节有提到所谓的『父进程、子进程』的关系,那我们登录 bash 之后, 就是取得一个名为 bash 的 PID 了,而在这个环境底下所运行的其他指令, 就几乎都是所谓的子进程了。那么,在这个单一的 bash 接口下,我可不可以进行多个工作啊? 当然可以啦!可以『同时』进行喔!举例来说,我可以这样做:
    [root@linux ~]# cp file1 file2 &
    
    在这一串指令中,重点在那个 & 的功能,他表示将 file1 这个文件拷贝为 file2 ,且放置于背景中运行, 也就是说运行这一个命令之后,在这一个终端接口仍然可以做其他的工作!而当这一个指令 ( cp file1 file2 )运行完毕之后,系统将会在您的终端接口显示完成的消息!很便利喔!

  • 多人多任务的系统资源分配问题考虑:
  • 多人多任务确实有很多的好处,但其实也有管理上的困扰,因为用户越来越多, 将导致你管理上的困扰哩!另外,由于用户日盛,当用户达到一定的人数后, 通常你的机器便需要升级了,因为 CPU 的运算与 RAM 的大小可能就会不敷使用!

    举个例子来说,鸟哥之前的网站管理的有点不太好,因为使用了一个很复杂的人数统计程序, 这个程序会一直去取用 MySQL 数据库的数据,偏偏因为流量大,造成 MySQL 很忙碌。 在这样的情况下,当鸟哥要登录去写网页数据,或者要去使用讨论区的资源时, 哇!慢的很!简直就是『龟速』啊!后来终于将这个程序停止不用了, 以自己写的一个小程序来取代,呵呵!这样才让 CPU 的负载 (loading) 整个降下来~ 用起来顺畅多了! ^_^

    好了!废话说完了!开始来谈一谈几个常用的指令吧!

    工作管理 (job control): &, [ctrl]-z, jobs, fg, bg, kill

    这个工作管理 (job control) 是用在 bash 环境下的,也就是说:『 当我们登录系统取得 bash shell 之后,在单一终端机接口下同时进行多个工作的行为管理 』。举例来说,我们在登录 bash 后, 想要一边拷贝文件、一边进行数据搜索、一边进行编译,还可以一边进行 vi 程序撰写! 当然我们可以重复登录那六个文本接口的终端机环境中,不过,能不能在一个 bash 内达成? 当然可以啊!就是使用 job control 啦! ^_^

    从上面的说明当中,您应该要了解的是:『进行工作管理的行为中, 其实每个工作都是目前 bash 的子进程,亦即彼此之间是有相关性的。 我们无法以 job control 的方式由 tty1 的环境去管理 tty2 的 bash !』 这个概念请您先创建起来,后续的范例介绍之后,您就会清楚的了解啰!

    或许你会觉得很奇怪啊,既然我可以在六个终端接口登录,那何必使用 job control 呢? 真是脱裤子放屁,多此一举啊!不要忘记了呢,我们可以在 /etc/security/limits.conf 里面设置用户同时可以登录的连接数,在这样的情况下,某些用户可能仅能以一个连接来工作呢! 所以啰,您就得要了解一下这种工作管理的模式了! 此外,这个章节内容也会牵涉到很多的数据流重导向,所以,如果忘记的话, 务必回到 BASH Shell 看一看喔!

    总之,要进行 bash 的 job control 必须要注意到的限制是:
    • 进程必须来是 shell 的 child process
    • 进程不能等待 terminal/shell 的输入(input)


  • 直接将指令丢到背景中『运行』的 & :
  • 瞎密?将某个指令『丢到背景』当中?在一个 bash 的环境下,什么叫做『前景 (foreground) 』与『背景 (background) 』?我们先来简单的定义一下:
    • 前景:您可以控制的这个工作称为前景的工作 (foreground);
    • 背景:在内存内可以自行运作的工作,您无法直接控制他,除非以 bg/fg 等指令将该工作调用出来。
    如同前面提到的,我们在只有一个 bash 的环境下,如果想要同时进行多个工作, 那么可以将某些工作丢到背景环境当中,让我们可以继续操作前景的工作!那么如何将工作丢到背景中? 最简单的方法就是利用『 & 』这个玩意儿了!举个简单的例子, 我们要将 /etc/ 整个备份成为 /tmp/etc.tar.gz 时,又不想要等待, 那么可以这样做:
    [root@linux ~]# tar -zpcf /tmp/etc.tar.gz /etc &
    [1] 24874   <== [job number] PID 
    [root@linux ~]#    <== 可以继续作业,不受影响!这就是前景!
    
    仔细的瞧一瞧,我在输入一个指令后,在该指令的最后面加上一个『 & 』代表将该指令丢到背景中, 此时 bash 会给予这个指令一个『工作号码(job number)』,就是那个 [1] 啦! 至于后面那个 24874 则是该指令所触发的『 PID 』了! 而且,有趣的是,我们可以继续操作 bash 呢!很不赖吧! 不过,那么丢到背景中的工作什么时候完成?完成的时候会显示什么? 如果你输入几个指令后,突然出现这个数据:
    [1]+  Done                    tar -zpcf /tmp/etc.tar.gz /etc
    
    就代表 [1] 这个工作已经完成 (Done) ,该工作的指令则是接在后面那一串指令列。 这样了解了吧?!另外,这个 & 代表:『将工作丢到背景中去运行』喔! 注意到那个『运行』的字眼!此外,这样的情况最大的好处是: 不怕被 [ctrl]-c 中断的啦!

    此外,将工作丢到背景当中要特别注意数据的流向喔!举例来说,如果我将刚刚那个指令改成:
    [root@linux ~]# tar -zpcvf /tmp/etc.tar.gz /etc &
    
    情况会怎样?呵呵,在背景当中运行的指令,如果有 stdout 及 stderr 时, 他的数据依旧是输出到屏幕上面的,所以,我们会无法看到提示字符,当然也就无法完好的掌握前景工作。 所以啰,最佳的状况就是利用数据流重导向,将输出数据发送至某个文件中。举例来说,我可以这样做:
    [root@linux ~]# tar -zpcvf /tmp/etc.tar.gz /etc > /tmp/log.txt 2>&1 &
    [1] 24984
    [root@linux ~]# 
    
    呵呵!如此一来,数据都给他发送到 /tmp/log.txt 当中,当然就不会影响到我们前景的作业了。 这样说,您应该可以更清楚数据流重导向的重要性了吧?!^_^


  • 将『目前』的工作丢到背景中『暂停』:[ctrl]-z
  • 想个情况:如果我正在使用 vi ,却发现我有个文件不知道放在哪里,需要到 bash 环境下去搜索,此时,是否要结束 vi 呢?呵呵!当然不需要啊!只要暂时将 vi 给他丢到背景当中等待即可。 例如以下的案例:
    [root@linux ~]# vi ~/.bashrc
    # 在 vi 的一般模式下,按下 [ctrl]-z 这两个按键
    [1]+  Stopped                 /usr/bin/vim ~/.bashrc
    [root@linux ~]#   <==顺利取得了前景的操控权!
    
    在 vi 的一般模式下,按下 [ctrl] 及 z 这两个按键,屏幕上会出现 [1] ,表示这是第一个工作, 而那个 + 代表目前在背景下缺省被取用的那个工作 (与 fg 这个指令有关 )! 而那个 Stopped 则代表目前这个工作的状态。在缺省的情况下,使用 [ctrl]-z 丢到背景当中的工作都是『暂停』的状态喔!


  • 观察目前的背景工作状态: jobs
  • [root@linux ~]# jobs [-lrs]
    参数:
    -l  :除了列出 job number 之外,同时列出 PID
    -r  :仅列出正在背景 run 的工作;
    -s  :仅列出正在背景当中暂停 (stop) 的工作。
    范例:
    
    范例一:观察目前的 bash 当中,所有的工作,与对应的 PID
    [root@linux ~]# jobs -l
    [1]+ 24988 Stopped                 /usr/bin/vim ~/.bashrc
    [2]- 25006 Stopped                 /usr/bin/vim ~/.bash_history
    
    如果想要知道目前有多少的工作在背景当中,就用 jobs 这个指令吧!一般来说,直接下达 jobs 即可! 不过,如果您还想要知道该 job number 的 PID 号码,可以加上 -l 这个参数啦! 在输出的信息当中,例如上表,仔细看到那个 + - 号喔!那个 + 代表缺省的取用工作。 所以说:『目前我有两个工作在背景当中,两个工作都是暂停的, 而如果我仅输入 fg 时,那么那个 [1] 会被拿到前景当中来处理』!


  • 将背景工作拿到前景来处理:fg
  • 刚刚提到的都是将工作丢到背景当中去运行的,那么有没有可以将背景工作拿到前景来处理的? 有啊!就是那个 fg 啦!举例来说,我们想要将上头范例当中的工作拿出来处理时:
    [root@linux ~]# fg %jobnumber
    参数:
    %jobnumber :工作的号码。注意,那个 % 是可有可无的!
    范例:
    
    范例一:先以 jobs 观察工作,再将工作取出:
    [root@linux ~]# jobs
    [1]+  Stopped                 /usr/bin/vim ~/.bashrc
    [2]-  Stopped                 /usr/bin/vim ~/.bash_history
    [root@linux ~]# fg      <==缺省取出那个 + 的工作,亦即 [1]
    [root@linux ~]# fg %2   <==直接规定取出的那个工作号码!
    
    经过 fg 指令就能够将背景工作拿到前景来处理啰!


  • 让工作在背景下进行: bg
  • 我们刚刚提到,那个 [ctrl]-z 可以将目前的工作丢到背景底下去『暂停』, 那么如何让一个工作在背景底下『 Run 』呢?我们可以在底下这个案例当中来测试! 注意喔!底下的测试要进行的快一点!^_^
    范例一:一运行 find / -perm +7000 后,立刻丢到背景去暂停!
    [root@linux ~]# find / -perm +7000
    # 此时,请立刻按下 [ctrl]-z 暂停!
    [1]+  Stopped                 find / -perm +7000
    [root@linux ~]#
    
    范例二:让该工作在背景下进行,并且观察他!!
    [root@linux ~]# jobs ; bg %1 ; jobs
    [1]+  Stopped                 find / -perm +7000
    [1]+ find / -perm +7000 &
    [1]+  Running                 find / -perm +7000 &
    
    看到哪里有差异吗?呼呼!没错!就是那个状态栏~以经由 Stopping 变成了 Running 啰! 看到差异点,嘿嘿!指令列最后方多了一个 & 的符号啰! 代表该工作被启动在背景当中了啦! ^_^


  • 管理背景当中的工作: kill
  • 刚刚我们可以让一个已经在背景当中的工作继续工作,也可以让该工作以 fg 拿到前景来, 那么,如果想要将该工作直接移除呢?或者是将该工作重新启动呢?呵呵! 这个时候就得需要给予该工作一个信号 (signal) ,让他知道该怎么作才好啊! 此时, kill 这个指令就派上用场啦!
    [root@linux ~]# kill -signal %jobnumber
    [root@linux ~]# kill -l
    参数:
    -l  :这个是 L 的小写,列出目前 kill 能够使用的信号 (signal) 有哪些?
    signal :代表给予后面接的那个工作什么样的指示啰!用 man 7 signal 可知:
      -1 :重新读取一次参数的设置档 (类似 reload);
      -2 :代表与由键盘输入 [ctrl]-c 同样的动作;
      -9 :立刻强制删除一个工作;
      -15:以正常的进程方式终止一项工作。与 -9 是不一样的。
    范例:
    
    范例一:找出目前的 bash 环境下的背景工作,并将该工作删除。
    [root@linux ~]# jobs
    [1]+  Stopped                 vim bashrc
    [root@linux ~]# kill -9 %1
    [1]+  已砍掉                  vim bashrc
    
    范例:找出目前的 bash 环境下的背景工作,并将该工作终止掉。
    [root@linux ~]# jobs
    [1]+  Stopped                 vim bashrc
    [root@linux ~]# kill -SIGTERM %1
    [1]+  终止                    vim bashrc
    # -SIGTERM 与 -15 是一样的!您可以使用 kill -l 来查阅!
    
    特别留意一下, -9 这个 signal 通常是用在『强制删除一个不正常的工作』时所使用的, -15 则是以正常步骤结束一项工作(15也是默认值),两者之间并不相同呦!举上面的例子来说, 我用 vi 的时候,不是会产生一个 .filename.swp 的文件吗? 那么,当使用 -15 这个 signal 时, vi 会尝试以正常的步骤来结束掉该 vi 的工作, 所以 .filename.swp 会主动的被移除,但若是使用 -9 这个 signal 时, 由于该 vi 工作会被强制移除掉,因此, .filename.swp 就会继续存在文件系统当中。 这样您应该可以稍微分辨一下了吧?

    其实, kill 的妙用是很无穷的啦!他搭配 signal 所详列的信息 (用 man 7 signal 去查阅相关数据) 可以让您有效的管理工作与进程 (Process),此外,那个 killall 也是同样的用法! 至于常用的 signal 您至少需要了解 1, 9, 15 这三个 signal 的意义才好。 此外, signal 除了以数值来表示之外,也可以使用信号名称喔! 举例来说,上面的范例二就是一个例子啦!至于 signal number 与名称的对应, 呵呵,使用 kill -l 就知道啦(L的小写)!

    进程管理

    本章一开始就提到所谓的『进程』的概念,包括进程的触发、子进程与父进程的相关性等等, 此外,还有那个『进程的相依性』以及所谓的『僵尸进程』等等需要说明的呢! 为什么进程管理这么重要呢?
    • 首先,由于我们在操作系统时,各项工作其实都是经过某个 PID 来达成的, 因此,能不能进行某项工作,就与该进程的权限有关了。
    • 再来,如果您的 Linux 系统是个很忙碌的系统,那么当整个系统资源快要被使用光时, 您是否能够找出最耗系统的那个进程,然后删除该进程,让系统恢复正常呢?
    • 此外,如果由于某个程序写的不好,导致产生一个有问题的进程在内存当中, 您又该如何找出他,然后将他移除呢?
    • 如果同时有五六项工作在您的系统当中运作,但其中有一项工作才是最重要的, 该如何让那一项重要的工作被最优先运行呢?
    所以啰,一个称职的系统管理员,必须要熟悉进程的管理流程才行,否则当系统发生问题时, 还真是很难解决问题呢!当然啦,进程的管理其实也是很难理解的部分, 尤其讲到子进程与父进程之间的关系,更不容易理解。伤脑筋啊!无论如何,咱们还是得来看一看, 系统上面到底有多少进程在运作啊?

    进程的观察

    既然进程这么重要,那么我们如何查阅系统上面正在运作当中的进程呢?很简单啊! 利用静态的 ps 或者是动态的 top,还能以 pstree 来查阅进程树之间的关系喔!


  • ps
  • [root@linux ~]# ps aux
    [root@linux ~]# ps -lA
    [root@linux ~]# ps axjf
    参数:
    -A  :所有的 process 均显示出来,与 -e 具有同样的效用;
    -a  :不与 terminal 有关的所有 process ;
    -u  :有效用户 (effective user) 相关的 process ;
    x   :通常与 a 这个参数一起使用,可列出较完整信息。
    输出格式规划:
    l   :较长、较详细的将该 PID 的的信息列出;
    j   :工作的格式 (jobs format)
    -f  :做一个更为完整的输出。
    特别说明:
    由于 ps 能够支持的 OS 类型相当的多,所以他的参数多的离谱!
    而且有没有加上 - 差很多!详细的用法应该要参考 man ps 喔!
    范例:
    
    范例一:将目前属于您自己这次登录的 PID 与相关信息列示出来
    [root@linux ~]# ps -l
    F S   UID   PID  PPID  C PRI  NI ADDR SZ WCHAN  TTY          TIME CMD
    0 S     0  5881  5654  0  76   0 -  1303 wait   pts/0    00:00:00 su
    4 S     0  5882  5881  0  75   0 -  1349 wait   pts/0    00:00:00 bash
    4 R     0  6037  5882  0  76   0 -  1111 -      pts/0    00:00:00 ps
    # 上面这个信息其实很多喔!各相关信息的意义为:
    # F	代表这个进程的旗标 (flag), 4 代表用户为 super user;
    # S	代表这个进程的状态 (STAT),关于各 STAT 的意义将在内文介绍;
    # PID	没问题吧!?就是这个进程的 ID 啊!底下的 PPID 则上父进程的 ID;
    # C	CPU 使用的资源百分比
    # PRI	这个是 Priority (优先运行序) 的缩写,详细后面介绍;
    # NI	这个是 Nice 值,在下一小节我们会持续介绍。
    # ADDR	这个是 kernel function,指出该进程在内存的那个部分。如果是个 running
    #	的进程,一般就是『 - 』的啦!
    # SZ	使用掉的内存大小;
    # WCHAN	目前这个进程是否正在运作当中,若为 - 表示正在运作;
    # TTY	登录者的终端机位置啰;
    # TIME	使用掉的 CPU 时间。
    # CMD	所下达的指令为何!?
    # 仔细看到每一个进程的 PID 与 PPID 的相关性为何喔!上头列出的三个进程中,
    # 彼此间可是有相关性的呐!
    
    范例二:列出目前所有的正在内存当中的进程:
    [root@linux ~]# ps aux
    USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
    root         1  0.0  0.1   1740   540 ?        S    Jul25   0:01 init [3]
    root         2  0.0  0.0      0     0 ?        SN   Jul25   0:00 [ksoftirqd/0]
    root         3  0.0  0.0      0     0 ?        S<   Jul25   0:00 [events/0]
    .....中间省略.....
    root      5881  0.0  0.3   5212  1204 pts/0    S    10:22   0:00 su
    root      5882  0.0  0.3   5396  1524 pts/0    S    10:22   0:00 bash
    root      6142  0.0  0.2   4488   916 pts/0    R+   11:45   0:00 ps aux
    
    范例三:以范例一的显示内容,显示出所有的进程:
    [root@linux ~]# ps -lA
    F S   UID   PID  PPID  C PRI  NI ADDR SZ WCHAN  TTY          TIME CMD
    4 S     0     1     0  0  76   0 -   435 -      ?        00:00:01 init
    1 S     0     2     1  0  94  19 -     0 ksofti ?        00:00:00 ksoftirqd/0
    1 S     0     3     1  0  70  -5 -     0 worker ?        00:00:00 events/0
    .....以下省略.....
    
    范例四:列出类似进程树的进程显示:
    [root@linux ~]# ps -axjf
    PPID  PID PGID  SID TTY   TPGID STAT UID  TIME COMMAND
       0    1    0    0 ?        -1 S      0  0:01 init [3]
       1    2    0    0 ?        -1 SN     0  0:00 [ksoftirqd/0]
    .....中间省略.....
       1 5281 5281 5281 ?        -1 Ss     0  0:00 /usr/sbin/sshd
    5281 5651 5651 5651 ?        -1 Ss     0  0:00  \_ sshd: dmtsai [priv]
    5651 5653 5651 5651 ?        -1 S    500  0:00      \_ sshd: dmtsai@pts/0
    5653 5654 5654 5654 pts/0  6151 Ss   500  0:00          \_ -bash
    5654 5881 5881 5654 pts/0  6151 S      0  0:00              \_ su
    5881 5882 5882 5654 pts/0  6151 S      0  0:00                  \_ bash
    5882 6151 6151 5654 pts/0  6151 R+     0  0:00                      \_ ps -axjf
    # 看出来了吧?其实鸟哥在进行一些测试时,都是以网络连接进主机来测试的,
    # 所以啰,你会发现,嘿嘿!其实进程之间是有相关性的啦!不过,
    # 其实还可以使用 pstree 来达成这个进程树喔!底下在仔细谈一谈。
    
    范例五:找出与 cron 与 syslog 这两个服务有关的 PID 号码?
    [root@linux ~]# ps aux | egrep '(cron|syslog)'
    root  1539  0.0  0.1  1616   616 ?        Ss  Jul25  0:03 syslogd -m 0
    root  1676  0.0  0.2  4544  1128 ?        Ss  Jul25  0:00 crond
    root  6157  0.0  0.1  3764   664 pts/0    R+  12:10  0:00 egrep (cron|syslog)
    # 所以号码是 1539 及 1676 这两个啰!就是这样找的啦!
    
    说真的,如果你曾经使用 man ps 的话,呵呵!可能会被里面的说明搞的一脸茫然~ 因为......支持的类型实在太多,所以, ps -aux 与 ps aux 显示的结果『可能』是不一样的, 那个 -u 后面接的是『有效的用户 ID』,所以, -ux 可能是『有一个 user 名称为 x 』 而如果没有 x 这个用户,那么屏幕上面会显示一个警告消息,并以 ps aux 来输出。 哇!真是麻烦~所以,您可以直接记得使用 ps aux 就好了!

    在缺省的情况下, ps 仅会列出与目前所在的 bash shell 有关的 PID 而已,所以, 当我使用 ps -l 的时候,只有三个 PID (范例一)。注意一下,我有一个 bash 的 PID , 而且也有一个 ps 的 PID ,了解了吧?呵呵!在 bash 里面运行程序时,是会触发一个新的 process 的喔!而且,两者之间是有相关性的,看 PID 与 PPID 的号码,你就会晓得两者的差异了!

    那么,什么是『有效用户 ID 』呢?还记得我们提过的 SUID 吧?我以 dmtsai 去运行 /usr/bin/passwd 取得的那个 process 竟然是 root 的权限喔! 此时,实际的用户 (real user) 是 dmtsai ,但是有效的用户 (effective user) 是 root 啦! 这样说,可以理解吧!?

    一般来说,鸟哥会建议您,直接使用『ps aux』这个指令参数即可, 显示的结果例如上面的范例二啰。在范例二的各个显示项目代表的意义为:
    • USER:该 process 属于那个用户帐号的?
    • PID :该 process 的号码。
    • %CPU:该 process 使用掉的 CPU 资源百分比;
    • %MEM:该 process 所占用的物理内存百分比;
    • VSZ :该 process 使用掉的虚拟内存量 (Kbytes)
    • RSS :该 process 占用的固定的内存量 (Kbytes)
    • TTY :该 process 是在那个终端机上面运作,若与终端机无关,则显示 ?,另外, tty1-tty6 是本机上面的登录者进程,若为 pts/0 等等的,则表示为由网络连接进主机的进程。
    • STAT:该进程目前的状态,主要的状态有:
      • R :该进程目前正在运作,或者是可被运作;
      • S :该进程目前正在睡眠当中 (可说是 idle 状态啦!),但可被某些信号 (signal) 唤醒。
      • T :该进程目前正在侦测或者是停止了;
      • Z :该进程应该已经终止,但是其父进程却无法正常的终止他,造成 zombie (疆尸) 进程的状态
    • START:该 process 被触发启动的时间;
    • TIME :该 process 实际使用 CPU 运作的时间。
    • COMMAND:该进程的实际指令为何?
    我们取这一行来做个简单的说明:
    root      5881  0.0  0.3   5212  1204 pts/0    S    10:22   0:00 su
    
    该进程属于 root 所有,他的 PID 号码是 5881,该进程对于 CPU 的使用率很低啊! 至于占用的物理内存大概有 0.3% 这么多。至于该进程使用掉的虚拟内存量为 5212 K, 物理内存为 1204 K,该进程属于 pts/0 这个终端机,看来这个进程应该是来自网络的连接登录。 该进程目前是 Sleep 的状态,但其实是可以被运行的。这个进程由今天的 10:22 开始运作, 不过,仅耗去 CPU 运作时间的 0:00 分钟。该进程的运行就是 su 这个指令啦!

    除此之外,我们必须要知道的是『疆尸 (zombie) 』进程是什么? 通常,造成疆尸进程的成因是因为该进程应该已经运行完毕,或者是因故应该要终止了, 但是该进程的父进程却无法完整的将该进程结束掉,而造成那个进程一直存在内存当中..... 如果您发现在某个进程的 CMD 后面还接上 <defunct> 时,就代表该进程是疆尸进程啦,例如:
    apache  8683  0.0  0.9 83384 9992 ?   Z  14:33   0:00 /usr/sbin/httpd <defunct>
    
    当系统不稳定的时候就容易造成所谓的疆尸进程,可能原因是因为程序写的不好啦, 或者是用户的操作习惯不良等等所造成。如果您发现系统中很多疆尸进程时, 呵呵!记得啊!要找出该进程的父进程,然后好好的做个追踪,好好的进行主机的环境优化啊! 看看有什么地方需要改善的,不要只是直接将他 kill 掉而已呢! 不然的话,万一他一直产生,那可就麻烦了! @_@


  • top
  • [root@linux ~]# top [-d] | top [-bnp]
    参数:
    -d  :后面可以接秒数,就是整个进程画面更新的秒数。缺省是 5 秒;
    -b  :以批量的方式运行 top ,还有更多的参数可以使用喔!
          通常会搭配数据流重导向来将批量的结果输出成为文件。
    -n  :与 -b 搭配,意义是,需要进行几次 top 的输出结果。
    -p  :指定某些个 PID 来进行观察监测而已。
    在 top 运行过程当中可以使用的按键指令:
    	? :显示在 top 当中可以输入的按键指令;
    	P :以 CPU 的使用资源排序显示;
    	M :以 Memory 的使用资源排序显示;
    	N :以 PID 来排序喔!
    	T :由该 Process 使用的 CPU 时间累积 (TIME+) 排序。
    	k :给予某个 PID 一个信号  (signal)
    	r :给予某个 PID 重新制订一个 nice 值。
    范例:
    
    范例一:每两秒钟更新一次 top ,观察整体信息:
    [root@linux ~]# top -d 2
    top - 18:30:36 up 30 days, 7 min,  1 user,  load average: 0.42, 0.48, 0.45
    Tasks: 163 total,   1 running, 161 sleeping,   1 stopped,   0 zombie
    Cpu(s):  4.7% us,  4.0% sy,  6.3% ni, 82.5% id,  0.4% wa,  0.1% hi,  2.0% si
    Mem:   1033592k total,   955252k used,    78340k free,   208648k buffers
    Swap:  1052216k total,      728k used,  1051488k free,   360248k cached
        <==如果加入 k 或 r 时,就会有相关的字样出现在这里喔!
      PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND 
     3981 apache    34  19 84012  11m 7352 S 17.3  1.2   0:00.09 httpd
     1454 mysql     16   0  289m  40m 2228 S  3.8  4.0 115:01.32 mysqld
     3985 dmtsai    15   0  2148  904  668 R  3.8  0.1   0:00.03 top
        1 root      16   0  3552  552  472 S  0.0  0.1   0:08.90 init
        2 root      RT   0     0    0    0 S  0.0  0.0   0:52.76 migration/0
        3 root      34  19     0    0    0 S  0.0  0.0   0:03.01 ksoftirqd/0
    
    范例二:将 top 的信息进行 2 次,然后将结果输出到 /tmp/top.txt
    [root@linux ~]# top -b -n 2 > /tmp/top.txt
    # 这样一来,嘿嘿!就可以将 top 的信息存到 /tmp/top.txt 文件中了。
    
    范例三:假设 10604 是一个已经存在的 PID ,仅观察该进程?
    [root@linux ~]# top -d 2 -p10604
    top - 13:53:00 up 51 days,  2:27,  1 user,  load average: 0.00, 0.00, 0.00
    Tasks:   1 total,   0 running,   1 sleeping,   0 stopped,   0 zombie
    Cpu(s):  0.0% us,  0.0% sy,  0.0% ni, 100.0% id,  0.0% wa,  0.0% hi,  0.0% si
    Mem:    385676k total,   371760k used,    13916k free,   131164k buffers
    Swap:  1020116k total,      880k used,  1019236k free,    95772k cached
    
      PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND  
    10604 root      16   0  5396 1544 1244 S  0.0  0.4   0:00.07 bash
    
    范例四:承上题,上面的 NI 值是 0 ,想要改成 10 的话?
    # 在范例三的 top 画面当中直接按下 r 之后,会出现如下的图样!
    top - 13:53:00 up 51 days,  2:27,  1 user,  load average: 0.00, 0.00, 0.00
    Tasks:   1 total,   0 running,   1 sleeping,   0 stopped,   0 zombie
    Cpu(s):  0.0% us,  0.0% sy,  0.0% ni, 100.0% id,  0.0% wa,  0.0% hi,  0.0% si
    Mem:    385676k total,   371760k used,    13916k free,   131164k buffers
    Swap:  1020116k total,      880k used,  1019236k free,    95772k cached
    PID to renice: 10604
      PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND  
    10604 root      16   0  5396 1544 1244 S  0.0  0.4   0:00.07 bash
    
    # 之后,可以输入 nice 值了!
    top - 13:53:00 up 51 days,  2:27,  1 user,  load average: 0.00, 0.00, 0.00
    Tasks:   1 total,   0 running,   1 sleeping,   0 stopped,   0 zombie
    Cpu(s):  0.0% us,  0.0% sy,  0.0% ni, 100.0% id,  0.0% wa,  0.0% hi,  0.0% si
    Mem:    385676k total,   371760k used,    13916k free,   131164k buffers
    Swap:  1020116k total,      880k used,  1019236k free,    95772k cached
    Renice PID 10604 to value: 10
      PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND  
    10604 root      30  10  5396 1544 1244 S  0.0  0.4   0:00.07 bash
    
    top 也是个挺不错的进程观察工具!但不同于 ps 是静态的结果输出, top 这个程序可以持续的监测 (monitor) 整个系统的进程工作状态,例如上面的范例一所示啊! 在缺省的情况下,每次更新进程资源的时间为 5 秒,不过,可以使用 -d 来进行修改。

    top 主要分为两个画面,上面的画面为整个系统的资源使用状态,基本上总共有六行, 显示的内容依序是:
    • 第一行:显示系统已启动的时间、目前上线人数、系统整体的负载(load)。 比较需要注意的是系统的负载,三个数据分别代表 1, 5, 10 分钟的平均负载。 一般来说,这个负载值应该不太可能超过 1 才对,除非您的系统很忙碌。 如果持续高于 5 的话,那么.....仔细的看看到底是那个进程在影响整体系统吧!

    • 第二行:显示的是目前的观察进程数量,比较需要注意的是最后的 zombie 那个数值,如果不是 0 ,嘿嘿!好好看看到底是那个 process 变成疆尸了吧?!

    • 第三行:显示的是 CPU 的整体负载,每个项目可使用 ? 查阅。需要观察的是 id (idle) 的数值,一般来说,他应该要接近 100% 才好,表示系统很少资源被使用啊! ^_^。

    • 第四行与第五行:表示目前的物理内存与虚拟内存 (Mem/Swap) 的使用情况。

    • 第六行:这个是当在 top 程序当中输入指令时,显示状态的地方。 例如范例四就是一个简单的使用例子。
    至于 top 底下的画面,则是每个 process 使用的资源情况。比较需要注意的是:
    • PID :每个 process 的 ID 啦!
    • USER:该 process 所属的用户;
    • PR :Priority 的简写,进程的优先运行顺序,越小越早被运行;
    • NI :Nice 的简写,与 Priority 有关,也是越小越早被运行;
    • %CPU:CPU 的使用率;
    • %MEM:内存的使用率;
    • TIME+:CPU 使用时间的累加;
    一般来说,如果鸟哥想要找出最损耗 CPU 资源的那个进程时,大多使用的就是 top 这支程序啦!然后强制以 CPU 使用资源来排序 (在 top 当中按下 P 即可), 就可以很快的知道啦! ^_^。多多爱用这个好用的东西喔!


  • pstree
  • [root@linux ~]# pstree [-Aup]
    参数:
    -A  :各进程树之间的连接以 ASCII 字符来连接;
    -p  :并同时列出每个 process 的 PID;
    -u  :并同时列出每个 process 的所属帐号名称。
    范例:
    
    范例一:列出目前系统上面所有的进程树的相关性:
    [root@linux ~]# pstree -A
    init-+-atd
         |-crond
         |-dhclient
         |-dovecot-+-dovecot-auth
         |         `-3*[pop3-login]
         |-events/0
         |-2*[gconfd-2]
         |-master-+-pickup
         |        `-qmgr
         |-6*[mingetty]
         |-sshd---sshd---sshd---bash---su---bash---pstree
         |-udevd
         `-xinetd
    # 注意一下,为了节省版面,所以鸟哥已经删去很多进程了!
    # 同时注意到 sshd--- 那一行,嘿嘿!有相关的进程都被列出在一起了!
    
    范例二:承上题,同时秀出 PID 与 users 
    [root@linux ~]# pstree -Aup
    init(1)-+-atd(16143)
            |-crond(1676)
            |-dhclient(21339)
            |-dovecot(1606)-+-dovecot-auth(1616)
            |               |-pop3-login(747,dovecot)
            |               |-pop3-login(10487,dovecot)
            |               `-pop3-login(10492,dovecot)
            |-events/0(3)
            |-gconfd-2(2352)
            |-gconfd-2(32158)
            |-master(1666)-+-pickup(10817,postfix)
            |              `-qmgr(1675,postfix)
            |-mingetty(1792)
            |-mingetty(21366)
            |-sshd(5281)---sshd(10576)---sshd(10578,vbird)---bash(10579)
            |-syslogd(1539)
            |-udevd(801)
            `-xinetd(1589)
    # 呵呵!在括号 () 内的即是 PID 以及该进程的 owner 喔!不过,由于我是使用 
    # root 的身份运行此一指令,所以啰,嘿嘿!属于root的可能就不会显示出来啦!
    
    如果要找进程之间的相关性,呵呵!这个 pstree 真是好用到不行! 直接输入 pstree 可以查到进程相关性,不过,有的时候由于语系的问题会出现乱码, 因此,建议直接使用 -A 用 ASCII 字符作为链接接口 (就是那个 +, -, |, ` 等等啦!) 会比较看的清楚点。另外,如果还想要知道 PID 与所属用户,加上 -u 及 -p 两个参数即可。 我们前面不是一直提到,如果子进程挂点或者是老是砍不掉子进程时, 该如何找到父进程吗?呵呵!用这个 pstree 就对了! ^_^

    进程的删除

    我们在前几个小节提到的『背景工作管理』当中提到过, 要给予某个已经存在的工作某些动作时,是直接给予一个信号 (signal) 给该 PID 即可。 常见的工作可以使用 kill -l (L 的小写) 来查阅!而主要的信号代号与名称对应及内容是:

    代号名称内容
    1SIGHUP代表『让该 PID 重新读取自己的设置档』 ,类似重新启动
    2SIGINT代表用键盘输入的 [ctrl]-c 来中断一个进程的进行。
    9SIGKILL代表强制中断一个进程的进行,如果该进程进行到一半, 那么尚未完成的部分可能会有『半产品』产生,类似 vim会有 .filename.swp 保留下来。
    15SIGTERM以正常的结束进程来终止该进程。由于是正常的终止, 所以后续的动作会将他完成。不过,如果该进程已经发生问题,就是无法使用正常的方法终止时, 输入这个 signal 也是没有用的。

    而 kill 可以帮我们将这个 signal 发送给某个工作 (%jobnumber) 或者是某个 PID (直接输入数字), 也就是说, kill 后面直接加数字与加上 % 的情况是不同的!这个很重要喔!不要搞错了。 我们就活用一下 kill 与刚刚上面提到的 ps 来做个简单的练习吧!

    例题:以 ps 找出 syslog 这个服务的 PID 后,再使用 kill 重新读取 syslog 的设置档数据:
    答:
      我们可以使用底下的方式找出 syslog 的 PID 喔!
        ps aux | grep 'syslog' | grep -v 'grep'| awk '{print $2}'
      接下来,再给予 kill -SIGHUP 的信号至该 PID ,所以,整个指令串可以这样写:
        kill -SIGHUP `ps aux|grep 'syslog'|grep -v 'grep'|awk '{print $2}'`
      然后立刻 tail -n 5 /var/log/messages 看看 syslog 有没有重新被启动啊?

    由于 kill 后面必须要加上 PID (或者是 job number),所以,通常 kill 都会配合 ps, pstree 等指令,因为我们必须要找到相对应的那个进程的 ID 嘛!但是,如此一来,很麻烦~ 有没有可以利用『下达指令的名称』来给予信号的?举例来说,能不能直接将 syslog 这个进程给予一个 SIGHUP 的信号呢?可以的!用 killall 吧!
    [root@linux ~]# killall [-iIe] [command name]
    参数:
    -i  :interactive 的意思,交互式的,若需要删除时,会出现提示字符给用户;
    -e  :exact 的意思,表示『后面接的 command name 要一致』,但整个完整的指令
          不能超过 15 个字符。
    -I  :指令名称(可能含参数)忽略大小写。
    范例:
    
    范例一:给予 syslogd 这个指令启动的 PID 一个 SIGHUP 的信号
    [root@linux ~]# killall -1 syslogd
    # 如果用 ps aux 仔细看一下,syslogd 才是完整的指令名称。但若包含整个参数,
    # 则 syslogd -m 0 才是完整的呢!
    
    范例二:强制终止所有以 httpd 启动的进程
    [root@linux ~]# killall -9 httpd
    
    总之,要删除某个进程,我们可以使用 PID 或者是启动该进程的指令名称, 而如果要删除某个服务呢?呵呵!最简单的方法就是利用 killall , 因为他可以将系统当中所有以某个指令名称启动的进程全部删除。 举例来说,上面的范例二当中,系统内所有以 httpd 启动的进程,就会通通的被删除啦! ^_^

    系统资源的观察

    除了系统的进程之外,我们还必须就系统的一些资源进行检查啊! 举例来说,我们使用 top 可以看到很多系统的资源对吧!那么,还有没有其他的工具可以查阅的? 当然有啊!底下这些工具指令可以玩一玩!


  • free
  • [root@linux ~]# free [-b|-k|-m|-g] [-t]
    参数:
    -b  :直接输入 free 时,显示的单位是 Kbytes,我们可以使用 b(bytes), m(Mbytes)
          k(Kbytes), 及 g(Gbytes) 来显示单位喔!
    -t  :在输出的最终结果,显示物理内存与 swap 的总量。
    范例:
    
    范例一:显示目前系统的内存容量
    [root@linux ~]# free -m
                 total       used       free     shared    buffers     cached
    Mem:           376        366         10          0        129         94
    -/+ buffers/cache:        141        235
    Swap:          996          0        995
    
    仔细看看,我的系统当中有 384 MB 左右的物理内存,我的 swap 有 1GB 左右, 那我使用 free -m 以 MBytes 来显示时,就会出现上面的信息。Mem 那一行显示的是物理内存的量, Swap 则是虚拟内存的量。 total 是总量, used 是已被使用的量, free 则是剩余可用的量。 后面的 shared/buffers/cached 则是在已被使用的量当中,用来作为缓冲及缓存的量。

    仔细的看到范例一的输出喔,我的 Linux 主机是很平凡的,根本没有什么工作, 但是,我的物理内存是几乎被用光光的情况呢!不过,至少有 129 MB 用在缓冲记忆工作, 94 MB 则用在缓存工作,也就是说,系统是『很有效率的将所有的内存用光光』, 目的是为了让系统的访问性能加速啦!

    很多朋友都会问到这个问题『我的系统明明很轻松,为何内存会被用光光?』 现在瞭了吧?没有错!被用光是正常的!而需要注意的反而是 swap 的量。一般来说, swap 最好不要被使用,尤其 swap 最好不要被使用超过 20% 以上, 如果您发现 swap 的用量超过 20% ,那么,最好还是买物理内存来插吧! 因为, Swap 的性能跟物理内存实在差很多,而系统会使用到 swap , 绝对是因为物理内存不足了才会这样做的!如此,了解吧!


  • uname
  • [root@linux ~]# uname [-asrmpi]
    参数:
    -a  :所有系统相关的信息;
    -s  :系统内核名称
    -r  :内核的版本
    -m  :本系统的硬件名称
    -p  :CPU 的类型
    -i  :硬件的平台 (ix86)
    范例:
    
    范例一:输出系统的基本信息
    [root@linux ~]# uname -a
    Linux linux.site 2.6.12-1.1398_FC4 #1 Fri Jul 15 00:52:32 EDT 2005 
    i686 i686 i386 GNU/Linux
    
    这个咚咚我们前面使用过很多次了喔!uname 可以列出目前系统的内核版本、 主要硬件平台以及 CPU 类型等等的信息。以上面范例一的状态来说,我的 Linux 主机使用的内核名称为 Linux,而主机名称为 linux.site,内核的版本为 2.6.12-1.1398_FC4,该内核版本创建的日期为 2005/07/15, 适用的硬件平台为 i386 以上等级的硬件平台喔。


  • uptime
  • 这个指令很单纯呢!就是显示出目前系统已经开机多久的时间,以及 1, 5, 15 分钟的平均负载就是了。还记得 top 吧?没错啦! 这个 uptime 可以显示出 top 画面的最上面一行!
    [root@linux ~]# uptime
     18:06:30 up 52 days,  6:40,  1 user,  load average: 0.00, 0.00, 0.00
    # 上面表示,目前是 18:06 ,本系统已经开机 52 天又 6:40 ,有 1 个用户在在线,
    # 平均负载很低,所以都是 0 啊!
    


  • netstat
  • 这个 netstat 也是挺好玩的,其实,这个指令比较常被用在网络的监控方面, 不过,在进程管理方面也是需要了解的啦!这个指令的运行如下所示:基本上, netstat 的输出分为两大部分,上面是网络接口相关的连接,下方则是与 unix 进程有关的项目。
    [root@linux ~]# netstat -[atunlp]
    参数:
    -a  :将目前系统上所有的连接、监听、Socket 数据都列出来
    -t  :列出 tcp 网络封包的数据
    -u  :列出 udp 网络封包的数据
    -n  :不已进程的服务名称,以端口号 (port number) 来显示;
    -l  :列出目前正在网络监听 (listen) 的服务;
    -p  :列出该网络服务的进程 PID 
    范例:
    
    范例一:列出目前系统已经创建的网络连接与 unix socket 状态
    [root@linux ~]# netstat
    Active Internet connections (w/o servers)
    Proto Recv-Q Send-Q Local Address        Foreign Address       State
    tcp        0    256 59-125-83-224.ad:ssh linux.test.s:52679    ESTABLISHED
    Active UNIX domain sockets (w/o servers)
    Proto RefCnt Flags       Type       State         I-Node Path
    unix  16     [ ]         DGRAM                    4870   /dev/log
    unix  2      [ ]         DGRAM                    3561   @udevd
    unix  3      [ ]         STREAM     CONNECTED     509237
    # 在上面的结果当中,显示了两个部分,分别是网络的连接以及 linux 上面的 socket 
    # 连接状态。在网络连接的部分主要内容为:
    # Proto :网络的封包协定,主要分为 TCP 与 UDP 封包,相关数据请参考服务器篇;
    # Recv-Q:非由用户程序链接到此 socket 的拷贝的总 bytes 数;
    # Send-Q:非由远程主机发送过来的 acknowledged 总 bytes 数;
    # Local Address  :本地端的 IP
    # Foreign Address:远程主机的 IP;
    # State :连接状态,主要有创建(ESTABLISED)及监听(LISTEN);
    # 至于 unix 传统的 socket 连接状态则是:
    # Proto :一般就是 unix 啦;
    # RefCnt:连接到此 socket 的进程数量;
    # Flags :连接的旗标;
    # Type  :socket 访问的类型。主要有确认连接的 STREAM 与不需确认的 DGRAM 两种;
    # State :CONNECTED 表示已经连接创建。
    # Path  :连接到此 socket 的相关程序的路径!或者是相关数据输出的路径。
    
    范例二:找出目前系统上已在监听的网络连接及其 PID
    [root@linux ~]# netstat -tulnp
    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:21      0.0.0.0:*        LISTEN  1598/vsftpd
    tcp        0      0 127.0.0.1:25    0.0.0.0:*        LISTEN  1666/master
    tcp        0      0 :::22           :::*             LISTEN  5281/sshd
    udp        0      0 0.0.0.0:68      0.0.0.0:*                21339/dhclient
    # 看到了吗?最后面一个字段就是该端口号被该 PID 或程序所启动的!
    
    范例三:将上述的本地端 0.0.0.0:21 那个网络服务关闭的话?
    [root@linux ~]# kill 1598
    [root@linux ~]# killall vsftpd
    
    很多朋友常常有疑问,那就是,我的主机目前到底开了几个门(ports), 呵呵!其实,不论主机提供什么样的服务,一定必须要有相对应的 program 在主机上面运行才行啊! 举例来说,我们鸟园的 Linux 主机提供的就是 WWW 服务,那么我的主机当然有一个程序在提供 WWW 的服务啊!呵呵!那就是 Apache 这个套件所提供的啦! ^_^。 所以,当我运行了这个程序之后,我的系统自然就可以提供 WWW 的服务了。那如何关闭啊? 就关掉该程序所触发的那个进程就好了!例如上面的范例三所提供的例子啊! ^_^


  • dmesg
  • 在开机的时候你会发现有很多的消息出现吧,例如 CPU 的形式、硬盘、 光盘型号及硬盘分割表等等,这些信息的产生都是内核 (kernel) 在进行硬件的测试与驱动啦。 但是消息都是『刷』的一声就跑过去了!完全来不及看!伤脑筋~

    这些消息有时候对于系统管理员是很重要的,因为他提供了系统的信息呀! 要看这些消息你可以用 dmesg 这个指令来观看! 因为消息实在太多了,所以可以加入这个管线指令『 | more 』来使画面暂停!

    范例一:输出所有的内核开机时的信息
    [root@linux ~]# dmesg | more
    
    范例二:搜索开机的时候,硬盘的相关信息为何?
    [root@linux ~]# dmesg | grep -i hd
        ide0: BM-DMA at 0xffa0-0xffa7, BIOS settings: hda:DMA, hdb:DMA
        ide1: BM-DMA at 0xffa8-0xffaf, BIOS settings: hdc:DMA, hdd:pio
    hda: ST320430A, ATA DISK drive
    hdb: Maxtor 5T030H3, ATA DISK drive
    hdc: CD-540E, ATAPI CD/DVD-ROM drive
    .....底下省略.....
    
    由范例二就知道我这部主机的硬盘是怎样了吧?!没错啦! 还可以查阅能不能找到网络卡喔!网络卡的代号是 eth ,所以,直接输入 dmesg | grep -i eth 试看看呢!


  • sar
  • 这个 sar 并不是系统缺省的安装套件,如果您不是选择全部安装的话,这个套件缺省是不装的。 不过,如果您是选择全部安装,嘿嘿!那就可以玩这个 sar 了。 这个 sar 的功能倒是可以玩一玩的,因为他可以在您想要主动侦测主机的资源状态, 然后绘制成为图表时,相当好用的一个工具喔!
    [root@linux ~]# sar [-ru] [秒数] [次数]
    参数:
    -u  :进行 CPU 资源的统计;
    -r  :进行主内存目前状态的分析
    范例:
    
    范例一:统计目前主机 CPU 状态,每秒一次,共计三次!
    [root@linux ~]# sar -u 1 3
    Linux 2.6.12-1.1398_FC4 (vbird.vbird.idv.tw)    09/16/05
    
    14:16:17          CPU     %user     %nice   %system   %iowait     %idle
    14:16:18          all      0.00      0.00      0.00      0.00    100.00
    14:16:19          all      0.00      0.00      0.00      0.00    100.00
    14:16:20          all      0.00      0.00      0.00      0.00    100.00
    Average:          all      0.00      0.00      0.00      0.00    100.00
    # 我这部主机单纯用在家里测试的,所以没有什么网络服务,看的出来,嘿嘿!很安静!
    
    范例二:统计目前主机内存的使用情况
    [root@linux ~]# sar -r 1 3
    Linux 2.6.12-1.1398_FC4 (vbird.vbird.idv.tw)    09/16/05
    
    14:17:40    kbmemfree kbmemused  %memused kbbuffers  kbcached kbswpfree 
    14:17:41        26004    359672     93.26    127528     83996   1019236
    14:17:42        26004    359672     93.26    127528     83996   1019236
    14:17:43        26004    359672     93.26    127528     83996   1019236
    Average:        26004    359672     93.26    127528     83996   1019236
    # 其实这个与 free 的输出结果也差不了太多啦!
    
    鸟哥倒是很喜欢使用 sar 来做背景主动侦测系统 CPU 的动作!参考看看先!

    关于进程的运行顺序:

    还记得我们提过的多人多任务环境吧?因为目前的 x86 平台的 CPU 可以做到多任务的行为, 所以啰,我们的 Linux 可以在 x86 上面『同时进行多个工作』的呢!那么多个工作是如何进行的呢? 其实每个工作都会进入到 CPU 的工作调度当中,并等待 CPU 来运行, 而 CPU 会根据每个工作的优先运行序 (priority) 来判断谁比较重要, 所以某个工作就可能会比较优先被运行完毕啦!

    也就是说, Linux 系统中,每个 process 都会拥有一个所谓的『优先运行序 (priority)』的属性, 利用该属性来让 CPU 判断那个工作是比较重要的,那个工作在一群工作当中就会优先被运行, 也让系统资源可以分配的更恰当。我们可以使用 ps 还观察优先运行序:
    [root@linux ~]# ps -l
    F S   UID   PID  PPID  C PRI  NI ADDR SZ WCHAN  TTY          TIME CMD
    0 S     0 18851 18827  0  77   0 -  1302 wait   pts/0    00:00:00 su
    4 S     0 18852 18851  0  76   0 -  1349 wait   pts/0    00:00:00 bash
    4 R     0 19510 18852  0  76   0 -  1111 -      pts/0    00:00:00 ps
    
    其中,那个 PRI 就是 Priority 的简写,而 NI 是 nice 的简写,这两个东西是凑在一起才产生目前的 PRI 值的! PRI 越小时,代表该进程可以具有『越早被优先运行』的意思,只是 PRI 是由系统动态产生的, 并不会是一直固定的值喔。至于那个 NI (nice) 则是我们操作值额外给予的一个数值, 他可以影响 PRI 的值,基本上,他的相关性是这样的:
    • PRI(new) = PRI(old) + nice
    不过您要特别留意到,如果原本的 PRI 是 50 ,并不是我们给予一个 nice = 5 ,就会让 PRI 变成 55 喔! 因为 PRI 是系统『动态』决定的,所以,虽然 nice 值是可以影响 PRI ,不过, 最终的 PRI 仍是要经过系统分析后才会决定的。另外, nice 值是有正负的喔,而既然 PRI 越小越早被运行, 所以,当 nice 值为负值时,那么该进程就会降低 PRI 值,亦即会变的较优先被处理。此外,您必须要留意到:
    • 一般用户的 nice 值为 0 ~ 19 ;
    • root 可用的 nice 值为 -20 ~ 19 ;
    • 一般用户仅可将 nice 值越调越高,如果本来 nice 为 5 ,则未来仅能调整到大于 5 的 nice ;
    • 一般用户仅能调整属于自己的进程的 nice 值。
    这也就是说,要调整某个进程的优先运行序,就是『调整该进程的 nice 值』啦!那么如何给予某个进程 nice 值呢?有两种方式,分别是:
    • 一开始运行程序就立即给予一个特定的 nice 值:用 nice 指令;
    • 调整某个已经存在的 PID 的 nice 值:用 renice 指令。


  • nice
  • [root@linux ~]# nice [-n] command
    参数:
    -n  :后面接一个数值,数值的范围 -20 ~ 19。
    范例:
    
    范例一:用 root 给一个 nice 植为 -5 ,用于运行 vi ,并观察该进程!
    [root@linux ~]# nice -n -5 vi &
    [1] 19542
    [root@linux ~]# ps -l
    F S   UID   PID  PPID  C PRI  NI ADDR SZ WCHAN  TTY          TIME CMD
    0 S     0 18851 18827  0  77   0 -  1302 wait   pts/0    00:00:00 su
    4 S     0 18852 18851  0  76   0 -  1349 wait   pts/0    00:00:00 bash
    4 T     0 19542 18852  0  72  -5 -  1063 finish pts/0    00:00:00 vi
    4 R     0 19543 18852  0  77   0 -  1110 -      pts/0    00:00:00 ps
    
    就如同前面说的, nice 是用来调整进程的运行优先级!这里只是一个运行的范例罢了! 通常什么时候要将 nice 值调大呢?举例来说,系统的背景工作中, 某些比较不重要的进程之进行:例如备份工作!由于备份工作相当的耗系统资源, 这个时候就可以将备份的指令之 nice 值调大一些,可以使系统的支持分配的更为公平!


  • renice
  • [root@linux ~]# renice [number] PID
    参数:
    PID :某个进程的 ID 啊!
    范例:
    
    范例一:以上面 nice 范例中 ps -l 的结果,将 18852 那个 PID 修改 nice 为 10
    [root@linux ~]# renice 10 18852
    18852: old priority 0, new priority 10
    [root@linux ~]# ps -l
    F S   UID   PID  PPID  C PRI  NI ADDR SZ WCHAN  TTY          TIME CMD
    0 S     0 18851 18827  0  77   0 -  1302 wait   pts/0    00:00:00 su
    4 S     0 18852 18851  0  85  10 -  1349 wait   pts/0    00:00:00 bash
    4 R     0 19593 18852  0  87  10 -  1111 -      pts/0    00:00:00 ps
    
    如果要调整的是已经存在的某个 process 的话,那么就得要使用 renice 了。使用的方法很简单, renice 后面接上数值及 PID 即可。因为后面接的是 PID ,所以您务必要以 ps 或者其他进程观察的指令去找出 PID 才行啊!

    刚好,由上面这个范例当中我们也看的出来,虽然修改的是 bash 那个 PID 为 18852 的进程, 但是该进程所触发的 ps 指令当中的 PID 同样的也有一个 nice = 10 的结果喔! 了解了吧?整个 nice 值是可以在父进程 --> 子进程之间传递的呢!

    另外,除了 renice 之外,其实那个 top 同样的也是可以调整 nice 值的! top 也是可以调整已经存在的某个 process 的 nice 喔!

    特殊文件与进程:

    我们在 文件与目录管理当中的 SUID/SGID/SBIT 提到这一些奇怪的特殊权限的文件,这些文件到底是怎么产生特殊权限的行程?还有, 在磁盘挂载的时候,有时老是出现『 device is busy 』的字样,真麻烦~到底是怎么回事啊? 我们底下就来谈一谈。

    SUID/SGID/SBIT 的概念

    虽然已经在前面的章节提过 SUID/SGID 等等的特殊权限,但是到底他是如何产生的? 首先,我们以条列式的方法列出用户是否能够操作 SUID/SGID 的指令吧!
    • 关于 SUID 的运行:
      • Set UID 的权限设置值,仅对 binary file 有效;
      • 程序操作者必须要拥有该 binary file 的可运行权限 (x) ;
      • 当程序操作者运行该具有 SUID 的 binary file 时,该 binary file 所触发的进程中, 该进程的有效用户 (effective user) 为该 binary file 的拥有者。
    很简单的概念吧!基本上,也就是说,用户所触发的 SUID 的进程中, 有效用户会变成该 SUID 指令的程序拥有者啦!我们以 pstree 配合 passwd 来做个实验好咯。 请您以 dmtsai 这个一般身份用户登录后,运行 passwd ,但是先不要输入密码, 然后以另外一个终端机登录系统,使用 pstree -u 后,应该会看到如下的画面喔:
    init-+-atd
         |-.....省略的啦..........
         |-sshd---sshd---bash(dmtsai)---passwd(root)
         |-.....省略的啦..........
         `-xinetd
    
    看到了吧?虽然我是以 dmtsai 的身份启动 bash ,然后在 bash 当中运行 /usr/bin/passwd, 不过由于 passwd 拥有 SUID 的权限设置,所以,在 run-time 的过程当中,嘿嘿! 我这个 dmtsai 在该 process 内可是拥有 /usr/bin/passwd 的 owner (亦即是 root ) 的权限喔!这样够明白了吧?!

    那么既然 SUID/SGID 的权限是比较可怕的,您该如何查找整个系统的 SUID/SGID 的文件呢? 应该是还不会忘记吧?使用 find 即可啊!
      find / -perm +6000

    /proc/* 代表的意义:

    其实,我们之前提到的所谓的进程都是在内存当中嘛!而内存当中的数据又都是写入到 /proc/* 这个目录下的,所以啰,我们当然可以直接观察 /proc 这个目录当中的文件啊! 如果您观察过 /proc 这个目录的话,应该会发现他有点像这样:
    [root@linux ~]# ll /proc 
    dr-xr-xr-x   5 root    root            0 Sep 12 14:12 1
    dr-xr-xr-x   5 root    root            0 Sep 15 12:01 10
    dr-xr-xr-x   5 dovecot dovecot         0 Sep 14 12:07 10487
    .....中间省略.....
    -r--r--r--   1 root    root            0 Sep 16 16:02 uptime
    -r--r--r--   1 root    root            0 Sep 16 16:02 version
    -r--r--r--   1 root    root            0 Sep 16 16:02 vmstat
    
    基本上,目前主机上面的各个进程的 PID 都是以目录的型态存在于 /proc 当中。 举例来说,我们开机所运行的第一支程序 init 他的 PID 是 1 , 这个 PID 的所有相关信息都写入在 /proc/1/* 当中!若我们直接观察 PID 为 1 的数据好了, 他有点像这样:
    [root@linux ~]# ll /proc/1
    dr-xr-xr-x  2 root root 0 Sep 16 16:04 attr
    -r--------  1 root root 0 Sep 16 16:04 auxv
    -r--r--r--  1 root root 0 Sep 16 10:23 cmdline
    lrwxrwxrwx  1 root root 0 Sep 16 10:23 cwd -> /
    -r--------  1 root root 0 Sep 16 16:04 environ
    lrwxrwxrwx  1 root root 0 Sep 16 10:23 exe -> /sbin/init
    .....以下省略.....
    
    里面的数据还挺多的,不过,比较有趣的其实是两个文件,分别是:
    • cmdline:这个进程被启动的指令串;
    • environ:这个进程的环境变量内容。
    很有趣吧!如果你查阅一下 cmdline 的话,就会发现:
    [root@linux ~]# cat /proc/1/cmdline
    init [3]
    
    就是这个指令与参数启动 init 的啦!这还是跟某个特定的 PID 有关的内容呢,如果是针对整个 Linux 系统相关的参数呢?那就是在 /proc 目录底下的文件啦!相关的文件与对应的内容是这样的:

    文件名文件内容
    /proc/cmdline加载 kernel 时所下达的相关参数!查阅此文件,可了解系统是如何启动的!
    /proc/cpuinfo本机的 CPU 的相关信息,包含时脉、类型与运算功能等
    /proc/devices这个文件记录了系统各个主要设备的主要设备代号,与 mknod 有关呢!
    /proc/filesystems目前系统已经加载的文件系统啰!
    /proc/interrupts目前系统上面的 IRQ 分配状态。
    /proc/ioports目前系统上面各个设备所配置的 I/O 地址。
    /proc/kcore这个就是内存的大小啦!好大对吧!但是不要读他啦!
    /proc/loadavg还记得 top 以及 uptime 吧?没错!上头的三个平均数值就是记录在此!
    /proc/meminfo使用 free 列出的内存信息,嘿嘿!在这里也能够查阅到!
    /proc/modules目前我们的 Linux 已经加载的模块列表,也可以想成是驱动程序啦!
    /proc/mounts系统已经挂载的数据,就是用 mount 这个指令调用出来的数据啦!
    /proc/swaps到底系统挂加载的内存在哪里?呵呵!使用掉的 partition 就记录在此啦!
    /proc/partitions使用 fdisk -l 会出现目前所有的 partition 吧?在这个文件当中也有纪录喔!
    /proc/pci在 PCI 总线上面,每个设备的详细情况!可用 lspci 来查阅!
    /proc/uptime就是用 uptime 的时候,会出现的信息啦!
    /proc/version内核的版本,就是用 uname -a 显示的内容啦!
    /proc/bus/*一些总线的设备,还有 USB 的设备也记录在此喔!

    其实,上面这些文件鸟哥在此建议您可以使用 cat 去查阅看看,不必深入了解, 不过,观看过文件内容后,毕竟会比较有感觉啦!如果未来您想要自行撰写某些工具软件, 那么这个目录底下的相关文件可能会对您有点帮助的喔!

    查找已打开文件或已运行进程打开之文件:

    其实还有一些与进程相关的指令可以值得参考与应用的,我们来谈一谈:

  • fuser
  • 如果当我们要卸载某个设备时,他老是告诉我们『 device is busy 』, 那么到底是那个进程在使用这个设备呢?举例来说,当无法 umount /home 时, 该怎么办?此时我们可以使用 fuser 来帮忙啦!
    [root@linux ~]# fuser [-ki] [-signal] file/dir
    参数:
    -k  :找出使用该文件/目录的 PID ,并试图以 SIGKILL 这个信号给予该 PID;
    -i  :必须与 -k 配合,在删除 PID 之前会先询问用户意愿!
    -signal:例如 -1 -15 等等,若不加的话,缺省是 SIGKILL (-9) 啰!
    范例:
    
    范例一:找出目前所在目录的使用 PID 为何?
    [root@linux ~]# fuser .
    .:                   18852c
    [root@linux ~]# ps aux | grep 18852
    root     18852  0.0  0.4   5396  1588 pts/0    SN   10:12   0:00 bash
    # 用这个方式就可以得到使用该目录的 PID 了。此外,为何使用 fuser 
    # 的输出当中,在 PID 后面会有 c 呢?他代表的意义为:
    # c :在当前的目录下;
    # e :可以被运行的;
    # f :是一个被打开的文件
    # r :代表 root directory
    
    范例二:找到 /var 底下属于 FIFO 类型的文件,并且找出访问该文件的进程
    [root@linux ~]# find /var -type p
    /var/spool/postfix/public/qmgr
    /var/spool/postfix/public/pickup
    [root@linux ~]# fuser /var/spool/postfix/public/qmgr
    /var/spool/postfix/public/qmgr:  1666  1675
    [root@linux ~]# ps aux | egrep '(1666|1675)'
    root    1666 0.0 0.3 5640 1516 ?  Ss Jul25  0:01 /usr/libexec/postfix/master
    postfix 1675 0.0 0.4 5744 1604 ?  S  Jul25  0:00 qmgr -l -t fifo -u
    
    范例三:同范例二,但试图删除该 PID?
    [root@linux ~]# fuser -ki /var/spool/postfix/public/qmgr
    /var/spool/postfix/public/qmgr:  1666  1675
    Kill process 1666 ? (y/N) n
    Kill process 1675 ? (y/N) n
    
    如何?很有趣的一个指令吧!通过这个 fuser 我们可以找出使用该文件、 目录的进程,借以观察的啦!

  • lsof
  • 相对于 fuser 是由文件或者设备去找出使用该文件或设备的进程,反过来说, 如何查出某个进程打开或者使用的文件与设备呢?呼呼!那就是使用 lsof 啰~
    [root@linux ~]# lsof [-Uu] [+d]
    参数:
    -a  :多项数据需要『同时成立』才显示出结果时!
    -U  :仅列出 Unix like 系统的 socket 文件类型;
    -u  :后面接 username,列出该用户相关进程所打开的文件;
    +d  :后面接目录,亦即找出某个目录底下已经被打开的文件!
    范例:
    
    范例一:列出目前系统上面所有已经被打开的文件与设备:
    [root@linux ~]# lsof
    COMMAND PID USER  FD  TYPE  DEVICE   SIZE    NODE NAME
    init      1 root cwd   DIR     3,1   4096       2 /
    init      1 root rtd   DIR     3,1   4096       2 /
    init      1 root txt   REG     3,1  34352  883193 /sbin/init
    .....底下省略.....
    # 注意到了吗?是的,在缺省的情况下, lsof 会将目前系统上面已经打开的
    # 文件全部列出来~所以,画面多的吓人啊!您可以注意到,第一个文件 init 运行的
    # 地方就在根目录,而根目录,嘿嘿!所在的 inode 也有显示出来喔!
    
    范例二:仅列出关于 root 的所有进程打开的 socket 文件
    [root@linux ~]# lsof -u root -a -U
    COMMAND     PID USER   FD   TYPE     DEVICE SIZE   NODE NAME
    kmodule     793 root    4u  unix 0xd744b700        3549 socket
    udevd       801 root    5u  unix 0xd744bb40        3561 socket
    syslogd    1539 root    0u  unix 0xd75946e0        4870 /dev/log
    # 注意到那个 -a 吧!如果你分别输入 lsof -u root 及 lsof -U ,会有啥信息?
    # 使用 lsof -u root -U 及 lsof -u root -a -U ,呵呵!都不同啦!
    # -a 的用途就是在解决同时需要两个项目都成立时啊! ^_^
    
    范例三:请列出目前系统上面所有的被启动的周边设备
    [root@linux ~]# lsof +d /dev
    COMMAND     PID    USER   FD   TYPE     DEVICE SIZE NODE NAME
    init          1    root   10u  FIFO       0,13      1834 /dev/initctl
    kmodule     793    root    2u   CHR        1,3      2135 /dev/null
    kmodule     793    root    3u   CHR        5,1      2134 /dev/console
    udevd       801    root    2u   CHR        1,3      2135 /dev/null
    syslogd    1539    root    0u  unix 0xd75946e0      4870 /dev/log
    xinetd     1589    root    1r   CHR        1,3      2135 /dev/null
    #看吧!因为设备都在 /dev 里面嘛!所以啰,使用搜索目录即可啊!
    
    范例四:秀出属于 root 的 bash 这支程序所打开的文件
    [root@linux ~]# lsof -u root | grep bash
    bash   26199 root  cwd   DIR   3,2   4096   159875 /root
    bash   26199 root  rtd   DIR   3,1   4096        2 /
    bash   26199 root  txt   REG   3,1 686520   294425 /bin/bash
    bash   26199 root  mem   REG   3,1  83160    32932 /usr/lib/gconv/BIG5.so
    bash   26199 root  mem   REG   3,1  46552   915764 /lib/libnss_files-2.3.5.so
    .....底下省略.....
    
    这个指令可以找出您想要知道的某个进程是否有激活哪些信息? 例如上头提到的范例四的运行结果呢! ^_^

  • pidof
  • [root@linux ~]# pidof [-sx] program_name
    参数:
    -s  :仅列出一个 PID 而不列出所有的 PID
    -x  :同时列出该 program name 可能的 PPID 那个进程的 PID
    范例:
    
    范例一:列出目前系统上面 init 以及 syslogd 这两个程序的 PID
    [root@linux ~]# pidof init syslogd
    1 2546
    # 理论上,应该会有两个 PID 才对。上面的显示也是出现了两个 PID 喔。
    # 分别是 init 及 syslogd 这两支程序的 PID 啦。
    
    范例二:找出 bash 即以 bash 为 PPID 的几个主要的 PID
    [root@linux ~]# pidof -x bash
    2961 2959 338
    # 因为我的系统被我登录之后,我就会主动取得一个 bash 的进程,所以啰,
    # 很自然就会拥有一个 PID 啊。只要我再以底下的方式,就可以取得我所想要的 PID 内容。
    [root@linux ~]# ps aux | egrep '(2961|2959|338)'
    dmtsai   338  0.0  0.1  6024 1536 pts/0    Ss   16:43   0:00 -bash
    kiki    2961  0.0  0.1  6025 1526 pts/0    Ss   17:43   0:00 -bash
    .....以下省略......
    
    很简单的用法吧,通过这个 pidof 指令,并且配合 ps aux 与正规表示法, 就可以很轻易的找到您所想要的进程内容了呢。

    参考数据

    本章习题练习

    ( 要看答案请将鼠标移动到『答:』底下的空白处,按下左键圈选空白处即可察看 )
    • 简单说明什么是程序 (program) 而什么是进程 (process)?
      程序 (program) 是系统上面可以被运行的文件,由于 Linux 的完整文件名 (由 / 写起) 仅能有一个, 所以 program 的文件名具有单一性。当程序被运行后,就会启动成进程 (process), 一个 program 可以被不同的用户或者相同的用户重复的运行成为多个进程, 且该程序所造成的进程还因为不同的用户,而有不同的权限,且每个 process 几乎都是独立的。
    • 我今天想要查找 /etc/crontab 与 crontab 这个程序的用法与写法,请问我该如何在线查找?
    • 查找 crontab 指令可以使用 man crontab 或 info crontab ,至于查找 /etc/crontab ,则可以使用 man 5 crontab 啰!
    • 我要如何查找 crond 这个 daemon 的 PID 与他的 PRI 值呢?
    • ps -aux | grep crond 即可查到!
    • 我要如何修改 crond 这个 PID 的优先运行序?
    • 先以 ps -aux 找到 crond 的 PID 后,再以: renice -n number PID 来调整!
    • 我是一般身份用户,我是否可以调整不属于我的进程的 nice 值?此外,如果我调整了我自己的进程的 nice 值到 10 ,是否可以将他调回 5 呢?
    • 不行!一般身份用户仅能调整属于自己的 PID 进程,并且,只能将 nice 值一再地调高,并不能调低,所以调整为 10 之后,就不能降回 5 啰!
    • 我要怎么知道我的网络卡在开机的过程中有没有被捉到?
    • 可以使用 dmesg 来视察!
    修改历史:
    • 2002/06/28:第一次完成
    • 2003/02/10:重新编排与加入 FAQ
    • 2005/09/07:将旧的文章移动到 此处
    • 2005/09/18:哈哈,终于将这篇写完啰。添加了一些简单的小指令啦。
    其他链接
    环境工程模式篇
    鸟园讨论区
    鸟哥旧站

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