|
最近更新日期:2005/09/18
本文已不再维护,更新文章请参考此处
在 Linux 当中, Linux 是如何分辨一个程序的呢?嗯!当我们的系统里面有太多的死亡的程序的时候,
应该怎样将该程序查出来之后并杀掉他呢?如果主机仅允许一次登入一个终端机画面,
如何从事多个工作的进行呢?还有,如何设定一个程序,让他的执行顺序可以比较快速呢?!
这个都是过程控制的重点项目呦!呵呵!另外一个又更常发生啦!如果我的 X-Window 死掉了!但是我的
Linux 基本上却还是活着的时候,那么是否需要重新 reboot 呢?还是有其他的方式可以重新启动 X-Window ?
仔细瞧一瞧整个 process 的概念喔!
|
1. 什么是程序 (Process):
1.1 程序与执行文件 (process & program)
1.2 Linux 的多人多任务环境
2. 工作管理 (job control):
&, [ctrl]-z, jobs,
fg, bg, kill
3. 程序管理
3.1 程序的观察: ps, top,
pstree
3.2 程序的删除: kill,
killall
3.3 系统资源的观察: free,
uname, uptime,
netstat, dmesg, sar
4. 关于程序的执行顺序:
nice, renice
5. 特殊档案与程序:
5.1 SUID/SGID/SBIT 的概念
5.2 /proc/* 代表的意义
5.3 查询已开启档案或已执行程序开启之档案: fuser,
lsof, pidof
6. 本章习题练习
7. 针对本文的建议:http://phorum.vbird.org/viewtopic.php?t=23890
什么是程序 (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 的小写) 来查阅!而主要的讯号代号与名称对应及内容是:
代号 | 名称 | 内容 |
1 | SIGHUP | 代表『让该 PID 重新读取自己的配置文件』
,类似重新启动 |
2 | SIGINT | 代表用键盘输入的 [ctrl]-c 来中断一个程序的进行。 |
9 | SIGKILL | 代表强制中断一个程序的进行,如果该程序进行到一半,
那么尚未完成的部分可能会有『半产品』产生,类似 vim会有 .filename.swp 保留下来。 |
15 | SIGTERM | 以正常的结束程序来终止该程序。由于是正常的终止,
所以后续的动作会将他完成。不过,如果该程序已经发生问题,就是无法使用正常的方法终止时,
输入这个 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 即可啊!
/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:哈哈,终于将这篇写完啰。新增了一些简单的小指令啦。
|
|