标签:
一个程序被加载到内存当中运行,那么在内存内的那个数据就被称为程序(process)。程序是操作系统上非常重要的概念, 所有系统上面跑的数据都会以程序的型态存在。那么系统的程序有哪些状态?不同的状态会如何影响系统的运行? 程序之间是否可以互相控管等等的,这些都是我们所必须要知道的项目。本节节选自鸟哥的 Linux 私房菜 -- 基础学习篇目录 第十七章、程序管理与 SELinux 初探
当我们登陆系统后,会取得一个 bash 的 shell ,然后,我们用这个 bash 提供的介面去运行另一个命令,例如 /usr/bin/passwd 或者是 touch 等等,那些另外运行的命令也会被触发成为 PID ,呵呵!那个后来运行命令才产生的 PID 就是『子程序』了,而在我们原本的 bash 环境下,就称为『父程序』了!
例题:
请在目前的 bash 环境下,再触发一次 bash ,并以『 ps -l 』这个命令观察程序相关的输出资讯。
答:
直接运行 bash ,会进入到子程序的环境中,然后输入 ps -l 后,出现:
F S UID PID PPID C PRI NI ADDR SZ WCHAN TTY TIME CMD 4 S 0 8074 8072 2 76 0 - 1287 wait pts/1 00:00:00 bash 0 S 0 8102 8074 4 76 0 - 1287 wait pts/1 00:00:00 bash 4 R 0 8118 8102 0 78 0 - 1101 - pts/1 00:00:00 ps有看到那个 PID 与 PPID 吗?第一个 bash 的 PID 与第二个 bash 的 PPID 都是 8074 啊, 因为第二个 bash 是来自於第一个所产生的嘛!另外,每部主机的程序启动状态都不一样, 所以在你的系统上面看到的 PID 与我这里的显示一定不同!那是正常的!详细的 ps 命令我们会在本章稍后介绍, 这里你只要知道 ps -l 可以查阅到相关的程序资讯即可。
很多朋友常常会发现:『咦!明明我将有问题的程序关闭了,怎么过一阵子他又自动的产生? 而且新产生的那个程序的 PID 与原先的还不一样,这是怎么回事呢?』不要怀疑,如果不是 crontab 工作排程的影响,肯定有一支父程序存在,所以你杀掉子程序后, 父程序就会主动再生一支!那怎么办?正所谓这:『擒贼先擒王』,找出那支父程序,然后将他删除就对啦!
既然程序这么重要,那么我们如何查阅系统上面正在运行当中的程序呢?很简单啊! 利用静态的 ps 或者是动态的 top,还能以 pstree 来查阅程序树之间的关系喔!
[root@www ~]# ps aux <==观察系统所有的程序数据 [root@www ~]# ps -lA <==也是能够观察所有系统的数据 [root@www ~]# ps axjf <==连同部分程序树状态 选项与参数: -A :所有的 process 均显示出来,与 -e 具有同样的效用; -a :不与 terminal 有关的所有 process ; -u :有效使用者 (effective user) 相关的 process ; x :通常与 a 这个参数一起使用,可列出较完整资讯。 输出格式规划: l :较长、较详细的将该 PID 的的资讯列出; j :工作的格式 (jobs format) -f :做一个更为完整的输出。
范例一:将目前属於您自己这次登陆的 PID 与相关资讯列示出来(只与自己的 bash 有关) [root@www ~]# ps -l F S UID PID PPID C PRI NI ADDR SZ WCHAN TTY TIME CMD 4 S 0 13639 13637 0 75 0 - 1287 wait pts/1 00:00:00 bash 4 R 0 13700 13639 0 77 0 - 1101 - pts/1 00:00:00 ps
系统整体的程序运行是非常多的,但如果使用 ps -l 则仅列出与你的操作环境 (bash) 有关的程序而已, 亦即最上一级的父程序会是你自己的 bash 而没有延伸到 init 这支程序去!那么 ps -l 秀出来的数据有哪些呢? 我们就来观察看看:
所以你看到的 ps -l 输出信息中,他说明的是:『bash 的程序属於 UID 为 0 的使用者,状态为睡眠 (sleep), 之所以为睡眠因为他触发了 ps (状态为 run) 之故。此程序的 PID 为 13639,优先运行顺序为 75 , 下达 bash 所取得的终端介面为 pts/1 ,运行状态为等待 (wait) 。』这样已经够清楚了吧? 您自己尝试解析一下那么 ps 那一行代表的意义为何呢? ^_^
接下来让我们使用 ps 来观察一下系统内所有的程序状态吧!
范例二:列出目前所有的正在内存当中的程序: [root@www ~]# ps aux USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND root 1 0.0 0.0 2064 616 ? Ss Mar11 0:01 init [5] root 2 0.0 0.0 0 0 ? S< Mar11 0:00 [migration/0] root 3 0.0 0.0 0 0 ? SN Mar11 0:00 [ksoftirqd/0] .....(中间省略)..... root 13639 0.0 0.2 5148 1508 pts/1 Ss 11:44 0:00 -bash root 14232 0.0 0.1 4452 876 pts/1 R+ 15:52 0:00 ps aux root 18593 0.0 0.0 2240 476 ? Ss Mar14 0:00 /usr/sbin/atd
你会发现 ps -l 与 ps aux 显示的项目并不相同!在 ps aux 显示的项目中,各栏位的意义为:
一般来说,ps aux 会依照 PID 的顺序来排序显示,我们还是以 13639 那个 PID 那行来说明!该行的意义为『 root 运行的 bash PID 为 13639,占用了 0.2% 的内存容量百分比,状态为休眠 (S),该程序启动的时间为 11:44 , 且取得的终端机环境为 pts/1 。』与 ps aux 看到的其实是同一个程序啦!这样可以理解吗? 让我们继续使用 ps 来观察一下其他的资讯吧!
范例三:以范例一的显示内容,显示出所有的程序: [root@www ~]# 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 ....(以下省略).... # 你会发现每个栏位与 ps -l 的输出情况相同,但显示的程序则包括系统所有的程序。 范例四:列出类似程序树的程序显示: [root@www ~]# ps axjf PPID PID PGID SID TTY TPGID STAT UID TIME COMMAND 0 1 1 1 ? -1 Ss 0 0:01 init [5] .....(中间省略)..... 1 4586 4586 4586 ? -1 Ss 0 0:00 /usr/sbin/sshd 4586 13637 13637 13637 ? -1 Ss 0 0:00 \_ sshd: root@pts/1 13637 13639 13639 13639 pts/1 14266 Ss 0 0:00 \_ -bash 13639 14266 14266 13639 pts/1 14266 R+ 0 0:00 \_ ps axjf .....(后面省略).....
范例五:找出与 cron 与 syslog 这两个服务有关的 PID 号码? [root@www ~]# ps aux | egrep ‘(cron|syslog)‘ root 4286 0.0 0.0 1720 572 ? Ss Mar11 0:00 syslogd -m 0 root 4661 0.0 0.1 5500 1192 ? Ss Mar11 0:00 crond root 14286 0.0 0.0 4116 592 pts/1 R+ 16:15 0:00 egrep (cron|syslog) # 所以号码是 4286 及 4661 这两个罗!就是这样找的啦!
apache 8683 0.0 0.9 83384 9992 ? Z 14:33 0:00 /usr/sbin/httpd <defunct>
相对於 ps 是撷取一个时间点的程序状态, top 则可以持续侦测程序运行的状态!使用方式如下:
接下来让我们实际观察一下如何使用 top 与 top 的画面吧![root@www ~]# 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 值。 q :离开 top 软件的按键。范例一:每两秒钟升级一次 top ,观察整体资讯: [root@www ~]# top -d 2 top - 17:03:09 up 7 days, 16:16, 1 user, load average: 0.00, 0.00, 0.00 Tasks: 80 total, 1 running, 79 sleeping, 0 stopped, 0 zombie Cpu(s): 0.5%us, 0.5%sy, 0.0%ni, 99.0%id, 0.0%wa, 0.0%hi, 0.0%si, 0.0%st Mem: 742664k total, 681672k used, 60992k free, 125336k buffers Swap: 1020088k total, 28k used, 1020060k free, 311156k cached <==如果加入 k 或 r 时,就会有相关的字样出现在这里喔! PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 14398 root 15 0 2188 1012 816 R 0.5 0.1 0:00.05 top 1 root 15 0 2064 616 528 S 0.0 0.1 0:01.38 init 2 root RT -5 0 0 0 S 0.0 0.0 0:00.00 migration/0 3 root 34 19 0 0 0 S 0.0 0.0 0:00.00 ksoftirqd/0top 也是个挺不错的程序观察工具!但不同於 ps 是静态的结果输出, top 这个程序可以持续的监测整个系统的程序工作状态。 在默认的情况下,每次升级程序资源的时间为 5 秒,不过,可以使用 -d 来进行修改。 top 主要分为两个画面,上面的画面为整个系统的资源使用状态,基本上总共有六行,显示的内容依序是:
- 第一行(top...):这一行显示的资讯分别为:
- 目前的时间,亦即是 17:03:09 那个项目;
- 启动到目前为止所经过的时间,亦即是 up 7days, 16:16 那个项目;
- 已经登陆系统的使用者人数,亦即是 1 user项目;
- 系统在 1, 5, 15 分钟的平均工作负载。我们在第十六章谈到的 batch 工作方式为负载小於 0.8 就是这个负载罗!代表的是 1, 5, 15 分钟,系统平均要负责运行几个程序(工作)的意思。 越小代表系统越闲置,若高於 1 得要注意你的系统程序是否太过繁复了!
- 第二行(Tasks...):显示的是目前程序的总量与个别程序在什么状态(running, sleeping, stopped, zombie)。 比较需要注意的是最后的 zombie 那个数值,如果不是 0 !好好看看到底是那个 process 变成僵尸了吧?
- 第三行(Cpus...):显示的是 CPU 的整体负载,每个项目可使用 ? 查阅。需要特别注意的是 %wa ,那个项目代表的是 I/O wait, 通常你的系统会变慢都是 I/O 产生的问题比较大!因此这里得要注意这个项目耗用 CPU 的资源喔! 另外,如果是多核心的设备,可以按下数字键『1』来切换成不同 CPU 的负载率。
- 第四行与第五行:表示目前的实体内存与虚拟内存 (Mem/Swap) 的使用情况。 再次重申,要注意的是 swap 的使用量要尽量的少!如果 swap 被用的很大量,表示系统的实体内存实在不足!
- 第六行:这个是当在 top 程序当中输入命令时,显示状态的地方。
至於 top 下半部分的画面,则是每个 process 使用的资源情况。比较需要注意的是:
- PID :每个 process 的 ID 啦!
- USER:该 process 所属的使用者;
- PR :Priority 的简写,程序的优先运行顺序,越小越早被运行;
- NI :Nice 的简写,与 Priority 有关,也是越小越早被运行;
- %CPU:CPU 的使用率;
- %MEM:内存的使用率;
- TIME+:CPU 使用时间的累加;
top 默认使用 CPU 使用率 (%CPU) 作为排序的重点,如果你想要使用内存使用率排序,则可以按下『M』, 若要回复则按下『P』即可。如果想要离开 top 则按下『 q 』吧!如果你想要将 top 的结果输出成为文件时, 可以这样做:
范例二:将 top 的资讯进行 2 次,然后将结果输出到 /tmp/top.txt [root@www ~]# top -b -n 2 > /tmp/top.txt # 这样一来,嘿嘿!就可以将 top 的资讯存到 /tmp/top.txt 文件中了。
[root@www ~]# pstree [-A|U] [-up] 选项与参数: -A :各程序树之间的连接以 ASCII 字节来连接; -U :各程序树之间的连接以万国码的字节来连接。在某些终端介面下可能会有错误; -p :并同时列出每个 process 的 PID; -u :并同时列出每个 process 的所属帐号名称。 范例一:列出目前系统上面所有的程序树的相关性: [root@www ~]# pstree -A init-+-acpid |-atd |-auditd-+-audispd---{audispd} <==这行与底下一行为 auditd 分出来的子程序 | `-{auditd} |-automount---4*[{automount}] <==默认情况下,相似的程序会以数字显示 ....(中间省略).... |-sshd---sshd---bash---pstree <==就是我们命令运行的那个相依性! ....(底下省略).... # 注意一下,为了节省版面,所以鸟哥已经删去很多程序了! 范例二:承上题,同时秀出 PID 与 users [root@www ~]# pstree -Aup init(1)-+-acpid(4555) |-atd(18593) |-auditd(4256)-+-audispd(4258)---{audispd}(4261) | `-{auditd}(4257) |-automount(4536)-+-{automount}(4537) <==程序相似但 PID 不同! | |-{automount}(4538) | |-{automount}(4541) | `-{automount}(4544) ....(中间省略).... |-sshd(4586)---sshd(16903)---bash(16905)---pstree(16967) ....(中间省略).... |-xfs(4692,xfs) <==因为此程序拥有者并非运行 pstree 者!所以列出帐号 ....(底下省略).... # 在括号 () 内的即是 PID 以及该程序的 owner 喔!不过,由於我是使用 # root 的身份运行此一命令,所以属於 root 的程序就不会显示出来啦!如果要找程序之间的相关性,这个 pstree 真是好用到不行!直接输入 pstree 可以查到程序相关性,如上表所示,还会使用线段将相关性程序连结起来哩! 一般连结符号可以使用 ASCII 码即可,但有时因为语系问题会主动的以 Unicode 的符号来连结, 但因为可能终端机无法支持该编码,或许会造成乱码问题。因此可以加上 -A 选项来克服此类线段乱码问题。
kill 可以帮我们将这个 signal 传送给某个工作 (%jobnumber) 或者是某个 PID (直接输入数字)。 要再次强调的是: kill 后面直接加数字与加上 %number 的情况是不同的! 这个很重要喔!因为工作控制中有 1 号工作,但是 PID 1 号则是专指『 init 』这支程序!你怎么可以将 init 关闭呢? 关闭 init ,你的系统就当掉了啊!所以记得那个 % 是专门用在工作控制的喔! 我们就活用一下 kill 与刚刚上面提到的 ps 来做个简单的练习吧!
例题: 以 ps 找出 syslog 这个程序的 PID 后,再使用 kill 传送信息,使得 syslog 可以重新读取配置档。 答: 由於需要重新读取配置档,因此 signal 是 1 号。至於找出 syslog 的 PID 可以是这样做: ps aux | grep ‘syslog‘ | grep -v ‘grep‘| awk ‘{print $2}‘ 接下来则是实际使用 kill -1 PID,因此,整串命令会是这样: kill -SIGHUP $(ps aux|grep ‘syslog‘|grep -v ‘grep‘|awk ‘{print $2}‘) 如果要确认有没有重新启动 syslog ,可以参考登录档的内容,使用如下命令查阅: tail -5 /var/log/messages 如果你有看到类似『Mar 19 15:08:20 www syslogd 1.4.1: restart』之类的字样,就是表示 syslogd 在 3/19 有重新启动 (restart) 过了!
由於 kill 后面必须要加上 PID (或者是 job number),所以,通常 kill 都会配合 ps, pstree 等命令,因为我们必须要找到相对应的那个程序的 ID 嘛!但是,如此一来,很麻烦~有没有可以利用『下达命令的名称』来给予讯号的?举例来说,能不能直接将 syslog 这个程序给予一个 SIGHUP 的讯号呢?可以的!用 killall 吧!
[root@www ~]# killall [-iIe] [command name] 选项与参数: -i :interactive 的意思,互动式的,若需要删除时,会出现提示字节给使用者; -e :exact 的意思,表示『后面接的 command name 要一致』,但整个完整的命令 不能超过 15 个字节。 -I :命令名称(可能含参数)忽略大小写。 范例一:给予 syslogd 这个命令启动的 PID 一个 SIGHUP 的讯号 [root@www ~]# killall -1 syslogd # 如果用 ps aux 仔细看一下,syslogd 才是完整的命令名称。但若包含整个参数, # 则 syslogd -m 0 才是完整的呢! 范例二:强制终止所有以 httpd 启动的程序 [root@www ~]# killall -9 httpd 范例三:依次询问每个 bash 程序是否需要被终止运行! [root@www ~]# killall -i -9 bash Kill bash(16905) ? (y/N) n <==这个不杀! Kill bash(17351) ? (y/N) y <==这个杀掉! # 具有互动的功能!可以询问你是否要删除 bash 这个程序。要注意,若没有 -i 的参数, # 所有的 bash 都会被这个 root 给杀掉!包括 root 自己的 bash 喔! ^_^总之,要删除某个程序,我们可以使用 PID 或者是启动该程序的命令名称, 而如果要删除某个服务呢?呵呵!最简单的方法就是利用 killall , 因为他可以将系统当中所有以某个命令名称启动的程序全部删除。 举例来说,上面的范例二当中,系统内所有以 httpd 启动的程序,就会通通的被删除啦! ^_^
[root@www ~]# free [-b|-k|-m|-g] [-t] 选项与参数: -b :直接输入 free 时,显示的单位是 Kbytes,我们可以使用 b(bytes), m(Mbytes) k(Kbytes), 及 g(Gbytes) 来显示单位喔! -t :在输出的最终结果,显示实体内存与 swap 的总量。 范例一:显示目前系统的内存容量 [root@www ~]# free -m total used free shared buffers cached Mem: 725 666 59 0 132 287 -/+ buffers/cache: 245 479 Swap: 996 0 996
[root@www ~]# uname [-asrmpi] 选项与参数: -a :所有系统相关的资讯,包括底下的数据都会被列出来; -s :系统核心名称 -r :核心的版本 -m :本系统的硬件名称,例如 i686 或 x86_64 等; -p :CPU 的类型,与 -m 类似,只是显示的是 CPU 的类型! -i :硬件的平台 (ix86) 范例一:输出系统的基本资讯 [root@www ~]# uname -a Linux www.vbird.tsai 2.6.18-92.el5 #1 SMP Tue Jun 10 18:49:47 EDT 2008 i686 i686 i386 GNU/Linux
[root@www ~]# uptime 15:39:13 up 8 days, 14:52, 1 user, load average: 0.00, 0.00, 0.00 # top 这个命令已经谈过相关资讯,不再聊!
[root@www ~]# netstat -[atunlp] 选项与参数: -a :将目前系统上所有的连线、监听、Socket 数据都列出来 -t :列出 tcp 网络封包的数据 -u :列出 udp 网络封包的数据 -n :不以程序的服务名称,以埠号 (port number) 来显示; -l :列出目前正在网络监听 (listen) 的服务; -p :列出该网络服务的程序 PID 范例一:列出目前系统已经创建的网络连线与 unix socket 状态 [root@www ~]# netstat Active Internet connections (w/o servers) <==与网络较相关的部分 Proto Recv-Q Send-Q Local Address Foreign Address State tcp 0 132 192.168.201.110:ssh 192.168.:vrtl-vmf-sa ESTABLISHED Active UNIX domain sockets (w/o servers) <==与本机的程序自己的相关性(非网络) Proto RefCnt Flags Type State I-Node Path unix 20 [ ] DGRAM 9153 /dev/log unix 3 [ ] STREAM CONNECTED 13317 /tmp/.X11-unix/X0 unix 3 [ ] STREAM CONNECTED 13233 /tmp/.X11-unix/X0 unix 3 [ ] STREAM CONNECTED 13208 /tmp/.font-unix/fs7100 ....(中间省略)....
范例一:输出所有的核心启动时的资讯 [root@www ~]# dmesg | more 范例二:搜寻启动的时候,硬盘的相关资讯为何? [root@www ~]# dmesg | grep -i hd ide0: BM-DMA at 0xd800-0xd807, BIOS settings: hda:DMA, hdb:DMA ide1: BM-DMA at 0xd808-0xd80f, BIOS settings: hdc:pio, hdd:pio hda: IC35L040AVER07-0, ATA DISK drive hdb: ASUS DRW-2014S1, ATAPI CD/DVD-ROM drive hda: max request size: 128KiB ....(底下省略)....
[root@www ~]# vmstat [-a] [延迟 [总计侦测次数]] <==CPU/内存等资讯 [root@www ~]# vmstat [-fs] <==内存相关 [root@www ~]# vmstat [-S 单位] <==配置显示数据的单位 [root@www ~]# vmstat [-d] <==与磁碟有关 [root@www ~]# vmstat [-p 分割槽] <==与磁碟有关 选项与参数: -a :使用 inactive/active(活跃与否) 取代 buffer/cache 的内存输出资讯; -f :启动到目前为止,系统复制 (fork) 的程序数; -s :将一些事件 (启动至目前为止) 导致的内存变化情况列表说明; -S :后面可以接单位,让显示的数据有单位。例如 K/M 取代 bytes 的容量; -d :列出磁碟的读写总量统计表 -p :后面列出分割槽,可显示该分割槽的读写总量统计表 范例一:统计目前主机 CPU 状态,每秒一次,共计三次! [root@www ~]# vmstat 1 3 procs -----------memory---------- ---swap-- -----io---- --system-- -----cpu------ r b swpd free buff cache si so bi bo in cs us sy id wa st 0 0 28 61540 137000 291960 0 0 4 5 38 55 0 0 100 0 0 0 0 28 61540 137000 291960 0 0 0 0 1004 50 0 0 100 0 0 0 0 28 61540 137000 291964 0 0 0 0 1022 65 0 0 100 0 0
标签:
原文地址:http://www.cnblogs.com/ysztcn/p/4179592.html