第十七章、程序管理与 SELinux 初探
---恢复内容开始---
什么是程序 (process)
在 Linux 底下所有的命令与你能够进行的动作都与权限有关, 而系统依据UID/GID以及文件的属性相关性判定你的权限!在 Linux 系统当中:『触发任何一个事件时,系统都会将他定义成为一个程序,并且给予这个程序一个 ID ,称为 PID,同时依据启发这个程序的使用者与相关属性关系,给予这个 PID 一组有效的权限配置。』 从此以后,这个 PID 能够在系统上面进行的动作,就与这个 PID 的权限有关了!
『运行一个程序或命令』就可以触发一个事件而取得一个 PID!系统仅认识 binary file,那么要让系统工作就需要启动一个 binary file,这个 binary file 就是程序 (program)!
『不同的使用者身份运行这个 program 时,系统给予的权限也都不相同!』举例来说,我们可以利用 touch 来创建一个空的文件,当 root 运行这个 touch 命令时,他取得的是 UID/GID = 0/0 的权限,而当 dmtsai (UID/GID=501/501) 运行这个 touch 时,他的权限就跟 root 不同!
![程序被加载成为程序以及相关数据的示意图 程序被加载成为程序以及相关数据的示意图](http://vbird.dic.ksu.edu.tw/linux_basic/0440processcontrol_files/process_1.gif)
图 1.1.1、程序被加载成为程序以及相关数据的示意图
如上图所示,程序一般是放置在实体磁碟中,然后透过使用者的运行来触发。触发后会加载到内存中成为一个个体,那就是进程。 为了操作系统可管理这个程序,因此进程有给予运行者的权限/属性等参数,并包括程序所需要的命令码与数据或文件数据等, 最后再给予一个 PID 。系统就是透过这个 PID 来判断该 process 是否具有权限进行工作的!
![程序与程序之间的差异 程序与程序之间的差异](http://vbird.dic.ksu.edu.tw/linux_basic/0440processcontrol_files/program_process.gif)
图 1.1.2、程序与进程之间的差异
也就是说,当我们登陆并运行 bash 时,系统已经给我们一个 PID 了,这个 PID 就是依据登陆者的 UID/GID (/etc/passwd) 来的~以上面的图 1.1.2 配合图 1.1.1 来做说明的话,我们知道 /bin/bash 是一个程序 (program),当 dmtsai 登陆后,他取得一个 PID 号码为 2234 的进程,这个进程的 User/Group 都是 dmtsai ,而当这个进程进行其他作业时,例如上面提到的 touch 这个命令时, 那么由这个进程衍生出来的其他进程在一般状态下,也会沿用这个进程的相关权限的!
让我们将程序与进程作个总结:
- 程序 (program):通常为 binary program ,放置在储存媒体中 (如硬盘、光盘、软盘、磁带等),
为实体文件的型态存在;
- 进程(process):程序被触发后,运行者的权限与属性、程序的程序码与所需数据等都会被加载内存中, 操作系统并给予这个内存内的单元一个识别码 (PID),可以说,进程就是一个正在运行中的程序。
- 子进程与父进程:
当我们登陆系统后,会取得一个 bash 的 shell ,然后,我们用这个 bash 提供的界面去运行另一个命令,例如 /usr/bin/passwd 或者是 touch 等等,那些另外运行的命令也会被触发成为 PID ,那个后来运行命令才产生的 PID 就是『子进程』了,而在我们原本的 bash 环境下,就称为『父程序』了!
![程序相关系之示意图 程序相关系之示意图](http://vbird.dic.ksu.edu.tw/linux_basic/0440processcontrol_files/ppid.gif)
图 1.1.3、进程相关系之示意图
进程彼此之间是有相关性的!以上面的图示来看,连续运行两个 bash 后,第二个 bash 的父进程就是前一个 bash。因为每个进程都有一个 PID ,那某个进程的父程序该如何判断?就透过 Parent PID (PPID) 来判断即可。此外,由十一章的 export 内容我们也探讨过环境变量的继承问题,子进程可以取得父进程的环境变量啦! 让我们来进行底下的练习,以了解什么是子进程/父进程。
例题: 请在目前的 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 工作排程的影响,肯定有一支父程序存在,所以你杀掉子程序后, 父程序就会主动再生一支!那怎么办?正所谓这:『擒贼先擒王』,找出那支父程序,然后将他删除就对啦!
- fork and exec:进程呼叫的流程
其实子进程与父进程之间的关系还挺复杂的,最大的复杂点在於进程互相之间的呼叫。在 Linux 的进程呼叫通常称为 fork-and-exec 的流程 (注1)!程序都会藉由父进程以复制 (fork) 的方式产生一个一模一样的子进程, 然后被复制出来的子进程再以 exec 的方式来运行实际要进行的程序,最终就成为一个子进程的存在。 整个流程有点像底下这张图:
![程序使用 fork and exec 呼叫的情况示意图 程序使用 fork and exec 呼叫的情况示意图](http://vbird.dic.ksu.edu.tw/linux_basic/0440processcontrol_files/fork-and-exec.gif)
图 1.1.4、程序使用 fork and exec 呼叫的情况示意图
(1)系统先以 fork 的方式复制一个与父进程相同的缓存进程,这个进程与父进程唯一的差别就是 PID 不同!
但是这个缓存进程还会多一个 PPID 的参数,PPID 如前所述,就是父进程的进程识别码啦!然后(2)缓存进程开始以 exec
的方式加载实际要运行的程序,以上述图示来讲,新的进程名称为 qqq ,最终子进程的程序码就会变成 qqq 了!
这样了解乎!
- 系统或网络服务:常驻在内存的程序
如果就我们之前学到的一些命令数据来看,其实我们下达的命令都很简单,包括用 ls 显示文件啊、用 touch 创建文件啊、rm/mkdir/cp/mv 等命令管理文件啊、chmod/chown/passwd 等等的命令来管理权限等等的,不过, 这些命令都是运行完就结束了。也就是说,该项命令被触发后所产生的 PID 很快就会终止呢! 那有没有一直在运行的程序啊?当然有啊!而且多的是呢!
举个简单的例子来说好了,我们知道系统每分钟都会去扫瞄 /etc/crontab 以及相关的配置档, 来进行工作排程吧?那么那个工作排程是谁负责的?当然不是鸟哥啊! 呵呵!是 crond 这个程序所管理的,我们将他启动在背景当中一直持续不断的运行, 套句以前 DOS 年代常常说的一句话,那就是『常驻在内存当中的进程』啦!
常驻在内存当中的进程通常都是负责一些系统所提供的功能以服务使用者各项任务,因此这些常驻程序就会被我们称为:服务 (daemon)。系统的服务非常的多, 不过主要大致分成系统本身所需要的服务,例如刚刚提到的 crond 及 atd ,还有 syslog 等等的。还有一些则是负责网络连线的服务,例如 Apache, named, postfix, vsftpd... 等等的。这些网络服务比较有趣的地方,在於这些进程被运行后,他会启动一个可以负责网络监听的端口 (port) ,以提供外部用户端 (client) 的连线要求。
我们现在知道了,其实在 Linux 底下运行一个命令时,系统会将相关的权限、属性、程序码与数据等均加载内存,
并给予这个单元一个程序识别码 (PID),最终该命令可以进行的任务则与这个 PID
的权限有关。根据这个说明,我们就可以简单的了解,为什么 Linux 这么多用户,但是却每个人都可以拥有自己的环境了吧!^_^
!底下我们来谈谈 Linux 多人多工环境的特色:
- 多人环境:
Linux 最棒的地方就在於他的多人多工环境了!那么什么是『多人多工』?在 Linux 系统上面具有多种不同的帐号,
每种帐号都有都有其特殊的权限,只有一个人具有至高无上的权力,那就是
root (系统管理员)。除了 root 之外,其他人都必须要受一些限制的!而每个人进入
Linux 的环境配置都可以随著每个人的喜好来配置 (还记得我们在第十一章 BASH
提过的 ~/.bashrc 吧?对了!就是那个光!)!现在知道为什么了吧?因为每个人登陆后取得的 shell 的 PID
不同嘛!
- 多工行为:
我们在第零章谈到 CPU 的速度,目前的 CPU 速度可高达几个 GHz。 这代表 CPU 每秒钟可以运行 109 这么多次命令。我们的 Linux 可以让 CPU 在各个工作间进行切换, 也就是说,其实每个工作都仅占去 CPU 的几个命令次数,所以 CPU 每秒就能够在各个程序之间进行切换啦! 谁叫 CPU 可以在一秒钟进行这么多次的命令运行。
CPU 切换程序的工作,与这些工作进入到 CPU 运行的排程 (CPU 排程,非 crontab 排程) 会影响到系统的整体效能!
目前 Linux 使用的多工切换行为是非常棒的一个机制,几乎可以将 PC 的性能整个压榨出来!
由於效能非常好,因此当多人同时登陆系统时,其实会感受到整部主机好像就为了你存在一般!
这就是多人多工的环境啦!(注2)
- 多重登陆环境的七个基本终端窗口:
在 Linux 当中,默认提供了六个文字界面登陆窗口,以及一个图形界面,你可以使用 [Alt]+[F1].....[F7] 来切换不同的终端机界面,而且每个终端机界面的登陆者还可以不同人! 很炫吧!这个东西可就很有用啦!尤其是在某个程序死掉的时候!
其实,这也是多工环境下所产生的一个情况啦!我们的 Linux
默认会启动六个终端机登陆环境的程序,所以我们就会有六个终端机介面。
您也可以减少啊!就是减少启动的终端机程序就好了。详细的数据可以先查阅 /etc/inittab
这个文件,未来我们在启动管理流程 (第二十章) 会再仔细的介绍的!
- 特殊的程序管理行为:
以前的鸟哥笨笨的,总是以为使用 Windows 98 就可以啦!后来,因为工作的关系,需要使用 Unix 系统,想说我只要在工作机前面就好,才不要跑来跑去的到 Unix 工作站前面去呢!所以就使用 Windows 连到我的 Unix 工作站工作!好死不死,我一个程序跑下来要 2~3 天,唉~偏偏常常到了第 2.5 天的时候, Windows 98 就给他挂点去!当初真的是给他怕死了~
后来因为换了新计算机,用了随机版的 Windows 2000 ,呵呵,这东西真不错 (指对单人而言) ,在死机的时候, 他可以仅将错误的程序踢掉,而不干扰其他的程序进行,呵呵! 从此以后,就不用担心会死机连连罗!不过,2000 毕竟还不够好,因为有的时候还是会死当!
那么 Linux 会有这样的问题吗?老实说, Linux 几乎可以说绝对不会死机的!因为他可以在任何时候, 将某个被困住的程序杀掉,然后再重新运行该程序而不用重新启动!够炫吧!那么如果我在 Linux 下以文字界面登陆,在萤幕当中显示错误信息后就挂了~动都不能动,该如何是好!? 这个时候那默认的七个窗口就帮上忙啦!你可以随意的再按 [Alt]+[F1].....[F7] 来切换到其他的终端机界面,然后以 ps -aux 找出刚刚的错误程序,然后给他 kill 一下,哈哈,回到刚刚的终端机界面!恩~棒!又回复正常罗!
为什么可以这样做呢?我们刚刚不是提过吗?每个程序之间可能是独立的,也可能有相依性,
只要到独立的程序当中,删除有问题的那个程序,当然他就可以被系统移除掉啦!^_^
- bash 环境下的工作管理 (job control)
我们在上一个小节有提到所谓的『父程序、子程序』的关系,那我们登陆 bash 之后, 就是取得一个名为 bash 的 PID 了,而在这个环境底下所运行的其他命令, 就几乎都是所谓的子程序了。那么,在这个单一的 bash 介面下,我可不可以进行多个工作啊? 当然可以啦!可以『同时』进行喔!举例来说,我可以这样做:
[root@www ~]# cp file1 file2 &
在这一串命令中,重点在那个 & 的功能,他表示将 file1 这个文件复制为 file2 ,且放置於背景中运行, 也就是说运行这一个命令之后,在这一个终端介面仍然可以做其他的工作!而当这一个命令 (cp file1 file2) 运行完毕之后,系统将会在你的终端介面显示完成的消息!很便利喔!
- 多人多工的系统资源分配问题考虑:
多人多工确实有很多的好处,但其实也有管理上的困扰,因为使用者越来越多, 将导致你管理上的困扰哩!另外,由於使用者日盛,当使用者达到一定的人数后, 通常你的机器便需要升级了,因为 CPU 的运算与 RAM 的大小可能就会不敷使用!
举个例子来说,鸟哥之前的网站管理的有点不太好,因为使用了一个很复杂的人数统计程序, 这个程序会一直去取用 MySQL 数据库的数据,偏偏因为流量大,造成 MySQL 很忙碌。 在这样的情况下,当鸟哥要登陆去写网页数据,或者要去使用讨论区的资源时, 哇!慢的很!简直就是『龟速』啊!后来终於将这个程序停止不用了, 以自己写的一个小程序来取代,呵呵!这样才让 CPU 的负载 (loading) 整个降下来~ 用起来顺畅多了! ^_^