第5章Linux系统管理 5.1进 程 管 理〖*4/5〗5.1.1进程与程序程序是为了完成某种任务而设计的软件,例如OpenOffice是程序。什么是进程呢?进程就是运行中的程序。 一个运行着的程序,可能有多个程序。例如Linux下的WWW服务器通常是Apache服务器,当管理员启动服务后,可能会有许多人来访问,也就是说许多用户来同时请求httpd服务,Apache服务器将会创建多个httpd进程来对其进行服务。 1. 进程分类 Linux操作系统包括以下三种不同类型的进程,每种进程都有自己的特点和属性。  (1) 交互进程: 由一个Shell启动的进程。交互进程既可以在前台运行,也可以在后台运行; (2) 批处理进程: 这种进程和终端没有联系,是一个进程序列; (3) 守护进程: Linux系统启动时启动的进程,并在后台运行。 值得一提的是守护进程总是活跃的,一般是后台运行,守护进程一般是由系统在开机时通过脚本自动激活启动或超级管理用户root来启动。例如在CentOS或Redhat中,可以定义httpd 服务器的启动脚本的运行级别,此文件位于/etc/init.d目录下,文件名是httpd,/etc/init.d/httpd就是httpd服务器的守护进程,当把它的运行级别设置为3和5时,当系统启动时,它会跟着启动。 由于守护进程是一直运行着的,所以它所处的状态是等待请求处理任务。例如,不管我们是不是在访问百度网站,百度的httpd服务都在运行,等待着用户来访问,也就是等待着任务处理。 如果就我们之前学到的一些命令来看,都很简单,包括用ls显示文件、rm/mkdir/cp/mv等指令管理文件、chmod/chown等指令管理权限等,不过,这些指令都是执行完就结束了。也就是说,该指令被触发后所产生的PID很快就会终止。那有没有一直在执行的进程?当然有,而且还很多。 这些常驻在内存当中的进程有很多,不过有一些系统本身所需要的服务,有一些则是负责网络联机的服务,例如 Apache、named、postfix、vsftpd等。这些网络服务比较有趣的地方在于这些进程被执行后,它会启动一个可以负责网络监听的端口(Port),以提供外部客户端(Client)的联机要求。 2. 进程的属性 内核的内部数据结构记录了有关每个进程的各种信息,其中有一些非常重要的。 (1) 进程ID(PID): 是唯一的数值,用来区分进程; (2) 父进程和父进程的ID(PPID); (3) 启动进程的用户ID(UID)和所归属的组(GID); (4) 进程状态: 状态分为运行R、休眠S、僵死Z; (5) 进程执行的优先级; (6) 进程所连接的终端名; (7) 进程资源占用: 例如占用资源大小(内存、CPU占用量)。 3. 父进程和子进程 它们的关系是管理和被管理的关系,当父进程终止时,子进程也随之而终止。但子进程终止,父进程并不一定终止。例如httpd服务器运行时,我们可以杀掉其子进程,父进程并不会因为子进程的终止而终止。 在进程管理中,当我们发现占用资源过多,或无法控制进程时,应该杀死它,以保护系统的稳定安全运行。其实子进程与父进程之间的关系还挺复杂的,最大的复杂点在于进程互相之间的呼叫,以及两者权限的相关性。 5.1.2进程与资源管理〖*2〗1. 工作管理工作管理(Job Control)是用在bash Shell环境下的,当我们登录系统进入bash Shell之后,在单一终端接口下同时进行多个工作的行为管理。举例来说,我们在登录Shell 后,想要一边复制文件、一边进行资料搜寻、一边进行编译,还可以一边进行vi编辑。当然我们可以重复登录6个终端接口环境中,不过,能不能在一个bash Shell内实现呢?当然可以,就是使用工作管理: 使用&,直接将命令丢到后台中执行。 在一个bash的环境下,什么叫做“前台(Foreground)”与“后台(Background)”,我们先来简单定义一下。 (1) 前台: 可以控制的这个工作称为前台的工作; (2) 后台: 在内存内可以自行运作的工作,无法直接控制它,除非以bg/fg等指令将该工作呼叫出来。 在只有一个bash的环境下,如果想要同时进行多个工作,那么可以将某些工作丢到后台环境当中,让我们可以继续操作前台的工作。那么如何将工作丢到后台中呢?最简单的方法就是利用“& ”。例如,我们在后台查看gedit文件: \[root@localhost~\]# gedit a & \[1\] 24874 <== \[job number\] 进程编号PID \[root@localhost~\]# <== 可以继续作业,不受影响,这就是前台注意,输入一个指令,在该指令的最后面加上一个“&”代表将该指令丢到后台中,此时bash会给予这个指令一个工作号码(Job Number),就是\[1\]。至于后面的24874则是该命令所触发的PID。而且,我们可以继续操作bash。不过,丢到后台中的工作什么时候完成,完成的时候会显示什么?如果输入几个指令后,突然出现数据: \[1\]+one 就代表\[1\]这个工作已经完成(Done),该工作的指令则是接在后面的那一串指令列。另外,这个&代表将工作丢到后台中去执行。这样的情况最大的好处是不怕被Ctrl+C中断。 2. 查询进程信息 我们如何查询系统上面正在运作当中的进程呢?利用静态的ps或者是动态的top,还能以pstree来查阅进程树之间的关系。 (1) ps\[root@localhost~\]# ps aux参数如下。 ① A : 所有的进程均显示出来; ② a : 不与终端有关的所有进程; ③ u : 有效使用者(Effective User)相关的进程; ④ x : 通常与 a 这个参数一起使用,可列出较完整的信息。 特别说明: 由于ps能够支持的操作系统类型相当得多,所以它的参数非常多,而且有没有加上 “”也有区别。更详细的用法应该要参考man ps。 【例51】列出目前所有的正在内存当中的进程。\[root@localhost~\]# ps aux USERPID%CPU%MEMVSZRSSTTYSTATSTART TIMECOMMANDroot 1 0.00.1 1740 540 ? S Jul25 0:01 init \[3\]root 2 0.00.0 0 0 ? SN Jul25 0:00 \[ksoftirqd/0\]root 3 0.0 0.0 0 0 ? S< Jul25 0:00 \[events/0\].....中间省略..... root 58810.00.3 52121204 pts/0 S 10:22 0:00 suroot 58820.00.3 53961524 pts/0 S 10:22 0:00 bashroot 61420.00.2 4488 916 pts/0 R+ 11:45 0:00 ps aux 一般来说,直接使用“ps aux”这个指令参数即可,显示的结果如【例51】。在【例51】中的各个显示项目代表的意义如下。 ① USER: 该进程属于哪个使用者账号。 ② PID: 该进程的号码。 ③ %CPU: 该进程使用掉的CPU资源百分比。 ④ %MEM: 该进程所占用的物理内存百分比。 ⑤ VSZ: 该进程使用掉的虚拟内存量(KB)。 ⑥ RSS: 该进程占用的固定的内存量(KB)。 ⑦ TTY: 该进程是在哪个终端上面运作,若与终端无关,则显示“?”,另外,tty1tty6是本机上面的登入者进程,若为pts/0等,则表示为由网络连接进主机的进程。 ⑧ STAT: 该进程目前的状态,主要的状态有如下几种。  R: 该进程目前正在运行,或者是可被运行;  S: 该进程目前正在睡眠当中,但可被某些信号(Signal)唤醒;  T: 该进程目前正在侦测或者是停止了;  Z: 该进程应该已经终止,但是其父进程却无法正常地终止它,造成僵死进程的状态。 ⑨ START: 该进程被触发启动的时间。 ⑩ TIME: 该进程实际使用CPU运行的时间。 COMMAND: 该进程的实际指令。 取这一行来做个简单的说明: root58810.00.352121204 pts/0S10:220:00 su该进程属于root所有,它的PID号码是5881,该进程对于CPU的使用率很低,至于占用的物理内存大概有0.3%。该进程使用掉的虚拟内存量为5212KB,物理内存为1204KB,该进程属于pts/0这个终端,应该是来自网络的联机登入。该进程目前是Sleep的状态,但其实是可以被执行的。这个进程由今天的10:22开始运行,不过,仅耗去CPU运作时间的0:00分钟。该进程的执行就是su这个指令。 【例52】列出类似进程树的进程显示。PPID PID PGID SID TTY TPGID STAT UID TIME COMMAND 0100 ?-1 S00:01 init \[3\] 1200 ?-1 SN 00:00 \[ksoftirqd/0\] .....中间省略..... 1 5281 5281 5281 ?-1 Ss0 0:00/usr/sbin/sshd 5281 5651 5651 5651 ?-1 Ss 0 0:00\\_ sshd: zdxy \[priv\] 5651 5653 5651 5651 ?-1 S5000:00\\_ sshd: zdxy@pts/0 5653 5654 5654 5654 pts/06151 Ss5000:00\\_ -bash 5654 5881 5881 5654 pts/06151 S0 0:00\\_ su 5881 5882 5882 5654 pts/06151 S0 0:00\\_ bash 5882 6151 6151 5654 pts/06151 R+ 0 0:00\\_ ps -axjf其实在进行测试时,都是以网络联机进主机来测试的,所以,其实进程之间是有相关性的。其实还可以使用pstree来达成这个进程树。 【例53】找出和cron与syslog这两个服务有关的PID号码。\[root@localhost~\]# ps aux | egrep '(cron|syslog)' root15390.00.11616 616 ?SsJul250:03 syslogd -m 0 root16760.00.245441128 ?SsJul250:00 crond root61570.00.13764 664 pts/0R+12:100:00 egrep (cron|syslog)(2) top \[root@localhost~\]# top \[-d\] | top \[-bnp\]参数如下。 ① d: 后面可以接秒数,就是整个进程画面更新的秒数,默认是5s; ② p: 指定某些PID来进行观察监测而已。 【例54】每2s更新一次top,观察整体信息。\[root@localhost~\]# 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 PID USER PRNIVIRTRESSHR S %CPU %MEMTIME+COMMAND 3981 apache3419 8401211m 7352 S 17.31.2 0:00.09 httpd 1454 mysql 16 0289m40m 2228 S3.84.0 115:01.32 mysqld 3985 zdxy15 02148904668 R3.80.1 0:00.03 top 1 root16 03552552472 S0.00.1 0:08.90 init 2 rootRT 0 000 S0.00.0 0:52.76 migration/0 3 root3419 000 S0.00.0 0:03.01 ksoftirqd/0top是个不错的进程观察工具。但不同于ps是静态的结果输出,top 这个进程可以持续地监测整个系统的进程工作状态。在默认的情况下,每次更新进程资源的时间为5s,不过,可以使用d来进行修改。 top主要分为两个画面,上半部分的画面为整个系统的资源使用状态,基本上总共有5行,显示的内容依序是如下。 ① 第一行: 显示系统已启动的时间、目前上线人数、系统整体的负载。比较需要注意的是系统的负载,三个数据分别代表1、5、10min的平均负载。一般来说,这个负载值应该不太可能超过1才对,除非系统很忙碌。如果持续高于5的话,那么需要仔细看看到底是哪个进程在影响整体系统。 ② 第二行: 显示的是目前的观察进程数量,比较需要注意的是最后的zombie那个数值,如果不是0,好好看看到底是哪个进程已经僵死。 ③ 第三行: 显示的是CPU的整体负载。需要观察的是id (idle空闲)的数值,一般来说,应该要接近100%才好,表示系统中很少资源被使用。 ④ 第四行与第五行: 表示目前的物理内存与虚拟内存(Mem/Swap)的使用情况。 至于top下半部分的画面,则是每个进程使用的资源情况。比较需要注意的有如下几个参数。 ① PID: 每个进程的ID; ② USER: 该进程所属的使用者; ③ PR: Priority 的简写,进程的优先执行顺序,越小就越早被执行; ④ NI: Nice 的简写,与Priority有关,也是越小就越早被执行; ⑤ %CPU: CPU的使用率; ⑥ %MEM: 内存的使用率; ⑦ TIME+: CPU使用时间的累加。 一般来说,如果想要找出最损耗CPU资源的进程时,大多使用的就是top命令。然后强制以CPU使用资源来排序(在top当中按下p即可),就可以很快地知道。 【例55】假设10604是一个已经存在的PID,观察该进程。\[root@localhost~\]# 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 PRNIVIRTRESSHR S %CPU %MEMTIME+COMMAND 10604 root16 05396 1544 1244 S0.00.4 0:00.07 bash(3) pstree \[root@localhost~\]# pstree \[-Aup\]参数如下。 ① A : 各进程树之间的连接以ASCII字符来连接; ② p : 同时列出每个进程的PID; ③ u : 同时列出每个进程的所属账号名称。 【例56】列出目前系统上所有的进程树的相关性。\[root@localhost~\]# 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那一行,相关的进程都被列在一起了。 【例57】继续例56,同时显示出PID与users。\[root@localhost~\]# pstree -Aup init(1)-+-atd(16143) |-crond(1676) |-dhclient(21339) |-dovecot(1606)-+-dovecot-auth(1616) | |-pop3-login(747,test) | |-pop3-login(10487, test) | `-pop3-login(10492, test) |-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,zdxy)---bash(10579) |-syslogd(1539) |-udevd(801) `-xinetd(1589)在括号()内的即是PID以及该进程的所有者。不过,由于是使用root的身份执行这个命令,所以,属于root的可能就不会显示出来。 如果要找进程之间的相关性,就要使用pstree。直接输入 pstree可以查询进程相关性,不过,有的时候由于语系的问题会出现乱码,因此,建议直接使用A用ASCII字符作为连结接口,会看得比较清楚。如果子进程僵死或遇到老是杀不掉的子进程时,该如何找到父进程呢?就要用这个pstree。 3. 进程的删除 (1) kill kill的应用是和ps或pgrep命令结合在一起使用的。 语法: \[root@localhost~\]# kill \[信号代码\]进程ID注: 信号代码可以省略,常用的信号代码是-9,表示强制终止。 【例58】终止所有的httpd进程。 查看httpd 服务器的进程,也可以用pgrepl httpd 来查看: \[root@localhost~\]# psauxf|grephttpd root49390.00.05160 708 pts/3S+ 13:100:00 \\_ grep httpd root48300.11.324232 10272 ?Ss 13:02 0:00/usr/sbin/httpd apache 48330.00.6243644932 ?S13:02 0:00\\_/usr/sbin/httpd apache 48340.00.6243644928 ?S13:02 0:00\\_/usr/sbin/httpd apache 48350.00.6243644928 ?S13:02 0:00\\_/usr/sbin/httpd apache 48360.00.6243644928 ?S13:02 0:00\\_/usr/sbin/httpd apache 48370.00.6243644928 ?S13:02 0:00\\_/usr/sbin/httpd apache 48380.00.6243644928 ?S13:02 0:00\\_/usr/sbin/httpd apache 48390.00.6243644928 ?S13:02 0:00\\_/usr/sbin/httpd apache 48400.00.6243644928 ?S13:02 0:00\\_/usr/sbin/httpd看上面输出中的第二列,就是进程PID,其中4830是httpd服务器的父进程,从4833~4840的进程都是4830的子进程。如果杀掉父进程4830的话,其下的子进程也会跟着终止。\[root@localhost~\]# kill 4840 <==杀掉4840这个进程 \[root@localhost~\]# ps -auxf |grep httpd <==查看结果,httpd服务器仍在运行 \[root@localhost~\]# kill 4830 <==杀掉httpd的父进程 \[root@localhost~\]# ps -aux |grep httpd<==查看httpd的其他子进程是否存在,httpd服务器是否仍在运行(2) killall 由于 kill 后面必须要加上PID(或者是Job Number),所以,通常kill都会配合ps、pstree等指令,因为必须要找到相对应的进程的ID。但是,如此一来很麻烦,有没有可以利用进程的名称来给予信号的命令呢?killall可以通过进程的名称,直接杀死所有进程。 语法: \[root@localhost~\]# killall正在运行的进程名killall也和ps或pgrep结合使用,比较方便,通过ps或pgrep来查看哪些程序在运行。 【例59】终止gaim进程。\[root@localhost beinan\]# pgrep -l gaim 2979 gaim \[root@localhost beinan\]# killall gaim4. 资源管理 上面我们介绍了有关进程管理的命令,下面介绍其他资源管理的方法。 (1) 查看内存资源信息free\[root@localhost~\]# free \[-b|-k|-m|-g\] \[-t\]参数如下。 ① b : 直接输入free时,显示的单位是KB,也可以使用 b(B)、m(MB)、k(KB),及 g(GB)来显示单位。 ② t : 在输出的最终结果中,显示物理内存与Swap的总量。 【例510】显示目前系统的内存容量。\[root@localhost~\]# free -m total usedfreesharedbufferscached Mem:37636610012994 -/+ buffers/cache: 141235 Swap:9960995仔细看看,系统当中有384MB左右的物理内存,Swap有1GB左右,使用freem以兆(MB)为单位来显示时,就会出现上面的信息。Mem那一行显示的是物理内存的量,Swap则是虚拟内存的量。total是总量,used是已被使用的量,free则是剩余可用的量。后面的shared/buffers/cached则是在已被使用的量当中,用来作为缓冲及快取的量。 仔细看【例510】的输出,物理内存几乎是被用光,不过,至少有129MB用在缓冲工作,94 MB则用在快取工作,也就是说,系统是很有效率地将所有的内存用光,目的是为了让系统的存取效能加速。 很多朋友都会问到这个问题,系统明明很轻松,为何内存会被用光?被用光是正常的,而需要注意的反而是虚拟内存Swap的量。一般来说,Swap 最好不要被使用,尤其 Swap 最好不要被使用超过20%以上,如果发现Swap的用量超过20%,那么最好还是增加物理内存。因为,Swap的效能跟物理内存实在差很多,而系统会使用到Swap,绝对是因为物理内存不足了才会这样做的。 (2) 查看开机信息dmesg 在开机的时候会发现有很多的讯息出现,例如 CPU 的形式、硬盘、光盘型号及硬盘分割表等,这些信息的产生都是内核(kerne)在进行硬件的测试与驱动。但是这些信息都是刷的一下就跑过去了,完全来不及看。 对于系统管理员这些信息有时候是很重要的,因为它提供了系统的信息,这些讯息可以用dmesg指令来查看。因为信息实在太多了,所以可以加入这个管道命令“ | more”来使画面暂停,翻页后慢慢研究。 【例511】输出所有的核心开机时的信息。\[root@localhost ~\]# dmesg|more【例512】搜寻开机的时候,硬盘的相关信息。\[root@localhost~\]# 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 .....以下省略.....由【例512】就知道这部主机的硬盘怎样了,还可以查阅网卡等,网卡的代号是eth,可以直接输入dmesg | grepi eth 试试看。 5.2文件系统与磁盘管理 系统管理员很重要的任务之一就是管理好自己的磁盘文件系统,每个分区不可太大也不能太小,太大会造成磁盘容量的浪费,太小则会产生文件无法存储的困扰。在本节我们的重点在于如何制作文件系统,包括分区、格式化与挂载等。 5.2.1文件系统类型与特性 目前Linux发行版默认使用的磁盘文件系统使用的是ext4,所以要了解文件系统就得由认识ext4开始。而文件系统是建立在硬盘上面的,因此我们得了解硬盘的物理组成才行。简单回顾一下磁盘物理组成的部分和磁盘分区。 1. 硬盘组成与分区 各种接口的磁盘在Linux中的文件名称分别如下。 (1) /dev/sd\[a-p\]\[1-15\]: 为SCSI、SATA、U盘等接口的磁盘文件名; (2) /dev/hd\[a-d\]\[1-63\]: 为IDE接口的磁盘文件名。 所谓的磁盘分区即指定分区的开始与结束磁柱,如此一来操作系统就能够知道它可以在所指定的区块内进行文件资料的读、写、搜寻等动作。 那么指定分区的磁柱范围记录在哪里?就是第一个扇区的分区表中。但是因为分区表仅有64B而已,因此最多只能记录4笔分区的记录,这4笔记录我们称为主分区或扩展分区,其中扩展分区还可以再分出逻辑驱动器,而能被格式化的则仅有主分区与逻辑驱动器而已。 最后,再说明一下分区的定义。 (1) 主分区与扩展分区最多可以有四个; (2) 扩展分区最多只能有一个; (3) 逻辑驱动器是由扩展分区持续分割出来的分区; (4) 能够被格式化后,作为数据存取的分区为主分区与逻辑驱动器,扩展分区无法格式化; (5) 逻辑驱动器的数量依操作系统而不同,在Linux系统中,IDE硬盘最多有59个逻辑驱动器(5号~63号),SATA硬盘则有11个逻辑驱动器(5号~15号)。 2. 文件系统特性 磁盘分区完毕后还需要进行格式化,之后操作系统才能够使用这个分区。为什么需要进行格式化呢?这是因为每种操作系统所设定的文件属性或权限并不相同,为了存放这些文件所需的数据,就需要将分区进行格式化,以成为操作系统能够利用的文件系统格式。在文件系统方面,Linux可以算得上操作系统中的“瑞士军刀”。Linux 支持许多种文件系统,从日志型文件系统到集群文件系统和加密文件系统。