进程与资源管理
本文数据主要针对 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 的概念喔!
例题:请在目前的 bash 环境下,再触发一次 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 是来自于第一个所产生的嘛! |
[root@linux ~]# cp file1 file2 &
在这一串指令中,重点在那个 & 的功能,他表示将 file1 这个文件拷贝为 file2 ,且放置于背景中运行,
也就是说运行这一个命令之后,在这一个终端接口仍然可以做其他的工作!而当这一个指令 (
cp file1 file2 )运行完毕之后,系统将会在您的终端接口显示完成的消息!很便利喔![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 当中,当然就不会影响到我们前景的作业了。
这样说,您应该可以更清楚数据流重导向的重要性了吧?!^_^[root@linux ~]# vi ~/.bashrc # 在 vi 的一般模式下,按下 [ctrl]-z 这两个按键 [1]+ Stopped /usr/bin/vim ~/.bashrc [root@linux ~]# <==顺利取得了前景的操控权!在 vi 的一般模式下,按下 [ctrl] 及 z 这两个按键,屏幕上会出现 [1] ,表示这是第一个工作, 而那个 + 代表目前在背景下缺省被取用的那个工作 (与 fg 这个指令有关 )! 而那个 Stopped 则代表目前这个工作的状态。在缺省的情况下,使用 [ctrl]-z 丢到背景当中的工作都是『暂停』的状态喔!
[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] 会被拿到前景当中来处理』!
[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 指令就能够将背景工作拿到前景来处理啰!
范例一:一运行 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 啰! 看到差异点,嘿嘿!指令列最后方多了一个 & 的符号啰! 代表该工作被启动在背景当中了啦! ^_^
[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 就会继续存在文件系统当中。 这样您应该可以稍微分辨一下了吧?
[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 就好了!
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 这个指令啦!
apache 8683 0.0 0.9 83384 9992 ? Z 14:33 0:00 /usr/sbin/httpd <defunct>当系统不稳定的时候就容易造成所谓的疆尸进程,可能原因是因为程序写的不好啦, 或者是用户的操作习惯不良等等所造成。如果您发现系统中很多疆尸进程时, 呵呵!记得啊!要找出该进程的父进程,然后好好的做个追踪,好好的进行主机的环境优化啊! 看看有什么地方需要改善的,不要只是直接将他 kill 掉而已呢! 不然的话,万一他一直产生,那可就麻烦了! @_@
[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 bashtop 也是个挺不错的进程观察工具!但不同于 ps 是静态的结果输出, top 这个程序可以持续的监测 (monitor) 整个系统的进程工作状态,例如上面的范例一所示啊! 在缺省的情况下,每次更新进程资源的时间为 5 秒,不过,可以使用 -d 来进行修改。
[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 就对了! ^_^
代号 | 名称 | 内容 |
1 | SIGHUP | 代表『让该 PID 重新读取自己的设置档』 ,类似重新启动 |
2 | SIGINT | 代表用键盘输入的 [ctrl]-c 来中断一个进程的进行。 |
9 | SIGKILL | 代表强制中断一个进程的进行,如果该进程进行到一半, 那么尚未完成的部分可能会有『半产品』产生,类似 vim会有 .filename.swp 保留下来。 |
15 | SIGTERM | 以正常的结束进程来终止该进程。由于是正常的终止, 所以后续的动作会将他完成。不过,如果该进程已经发生问题,就是无法使用正常的方法终止时, 输入这个 signal 也是没有用的。 |
例题:以 ps 找出 syslog 这个服务的 PID 后,再使用 kill 重新读取 syslog 的设置档数据: 答:
|
[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 启动的进程,就会通通的被删除啦! ^_^
[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 则是在已被使用的量当中,用来作为缓冲及缓存的量。
[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 以上等级的硬件平台喔。
[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 啊!
[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 的服务了。那如何关闭啊? 就关掉该程序所触发的那个进程就好了!例如上面的范例三所提供的例子啊! ^_^
范例一:输出所有的内核开机时的信息 [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 试看看呢!
[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 的动作!参考看看先!
[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 的值,基本上,他的相关性是这样的:
[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 值调大一些,可以使系统的支持分配的更为公平!
[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 才行啊!
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 ) 的权限喔!这样够明白了吧?!
[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 .....以下省略.....里面的数据还挺多的,不过,比较有趣的其实是两个文件,分别是:
[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 的设备也记录在此喔! |
[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 我们可以找出使用该文件、 目录的进程,借以观察的啦!
[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 .....底下省略.....这个指令可以找出您想要知道的某个进程是否有激活哪些信息? 例如上头提到的范例四的运行结果呢! ^_^
[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 与正规表示法, 就可以很轻易的找到您所想要的进程内容了呢。