第十七章程序管理与 SELinux 初探

Posted crazyYong

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了第十七章程序管理与 SELinux 初探相关的知识,希望对你有一定的参考价值。

1. 什么是程序 (Process)
  1.1 程序与程序 (process & program): 子程序与父程序, fork-and-exec, 系统服务
  1.2 Linux 的多人多工环境
2. 工作管理 (job control)
  2.1 什么是工作管理
  2.2 job control 的管理:&, [ctrl]-z, jobs, fg, bg, kill
  2.3 离线管理问题: nohup
3. 程序管理
  3.1 程序的观察: ps (ps -l, ps aux, zombie), top, pstree
  3.2 程序的管理: signal, kill, killall
  3.3 关於程序的运行顺序: priority, nice, renice
  3.4 系统资源的观察: free, uname, uptime, netstat, dmesg, vmstat
4. 特殊文件与程序
  4.1 具有 SUID/SGID 权限的命令运行状态
  4.2 /proc/* 代表的意义
  4.3 查询已开启文件或已运行程序开启之文件: fuser, lsof, pidof
5. SELinux 初探
  5.1 什么是 SELinux: 目标, DAC, MAC
  5.2 SELinux 的运行模式: 组件, 安全性本文, domain/type
  5.3 SELinux 的启动、关闭与观察: getenforce, sestatus, 启动与关闭, setenforce
  5.4 SELinux 网络服务运行范例: 启动 (ps -Z), 错误情况, 解决 (chcon, restorecon)
  5.5 SELinux 所需的服务: setroubleshoot, sealert, auditd, audit2why
  5.6 SELinux 的政策与守则管理: seinfo, sesearch, getsebool, setsebool, semanage
6. 重点回顾


 1. 什么是程序 (Process)

由前面一连几个章节的数据看来,我们一直强调在 Linux 底下所有的命令与你能够进行的动作都与权限有关, 而系统如何判定你的权限呢?当然就是第十四章帐号管理当中提到的 UID/GID 的相关概念,以及文件的属性相关性罗!再进一步来解释,你现在大概知道,在 Linux 系统当中:触发任何一个事件时,系统都会将他定义成为一个程序,并且给予这个程序一个 ID ,称为 PID,同时依据启发这个程序的使用者与相关属性关系,给予这个 PID 一组有效的权限配置。』 从此以后,这个 PID 能够在系统上面进行的动作,就与这个 PID 的权限有关了!

看这个定义似乎没有什么很奇怪的地方,不过,您得要了解什么叫做『触发事件』才行啊!

----------------------------------------------------------------------------------------------------------------------------------------------------------

1.1 程序与程序 (process & program): 子程序与父程序, fork-and-exec, 系统服务

 

1.程序与程序 (process & program)

我们如何产生一个程序呢?其实很简单啦,就是『运行一个程序或命令』就可以触发一个事件而取得一个 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 不同啦!我们将这个概念绘制成图示来瞧瞧如下:

如上图所示,程序一般是放置在实体磁碟中,然后透过使用者的运行来触发。触发后会加载到内存中成为一个个体,那就是程序。 为了操作系统可管理这个程序,因此程序有给予运行者的权限/属性等参数,并包括程序所需要的命令码与数据或文件数据等, 最后再给予一个 PID 。系统就是透过这个 PID 来判断该 process 是否具有权限进行工作的!他是很重要的哩!

我们要操作系统的时候,通常是利用连线程序或者直接在主机前面登陆,然后取得我们的 shell 对吧!那么,我们的 shell 是 bash 对吧,这个 bash 在 /bin/bash 对吧,那么同时间的每个人登陆都是运行 /bin/bash 对吧!不过,每个人取得的权限就是不同!也就是说,我们可以这样看:

也就是说,当我们登陆并运行 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),可以说,程序就是一个正在运行中的程序。

 ----------------------------------------------------------------------

 2.子程序与父程序:

 在上面的说明里面,我们有提到所谓的『衍生出来的程序』,那是个啥咚咚?这样说好了,当我们登陆系统后,会取得一个 bash 的 shell ,然后,我们用这个 bash 提供的介面去运行另一个命令,例如 /usr/bin/passwd 或者是 touch 等等,那些另外运行的命令也会被触发成为 PID ,呵呵!那个后来运行命令才产生的 PID 就是『子程序』了,而在我们原本的 bash 环境下,就称为『父程序』了!借用我们在 十一章 Bash 谈到的 export 所用的图示好了:

所以你必须要知道,程序彼此之间是有相关性的!以上面的图示来看,连续运行两个 bash 后,第二个 bash 的父程序就是前一个 bash。因为每个程序都有一个 PID ,那某个程序的父程序该如何判断?就透过 Parent PID (PPID) 来判断即可。此外,由十一章的 export 内容我们也探讨过环境变量的继承问题,子程序可以取得父程序的环境变量啦! 让我们来进行底下的练习,以了解什么是子程序/父程序。

很多朋友常常会发现:『咦!明明我将有问题的程序关闭了,怎么过一阵子他又自动的产生? 而且新产生的那个程序的 PID 与原先的还不一样,这是怎么回事呢?』不要怀疑,如果不是 crontab 工作排程的影响,肯定有一支父程序存在,所以你杀掉子程序后, 父程序就会主动再生一支!那怎么办?正所谓这:『擒贼先擒王』,找出那支父程序,然后将他删除就对啦!

 ----------------------------------------------------------------------

3.fork and exec:程序呼叫的流程
其实子程序与父程序之间的关系还挺复杂的,最大的复杂点在於程序互相之间的呼叫。在 Linux 的程序呼叫通常称为 fork-and-exec 的流程 (注1)!程序都会藉由父程序以复制 (fork) 的方式产生一个一模一样的子程序, 然后被复制出来的子程序再以 exec 的方式来运行实际要进行的程序,最终就成为一个子程序的存在。 整个流程有点像底下这张图:

(1)系统先以 fork 的方式复制一个与父程序相同的缓存程序,这个程序与父程序唯一的差别就是 PID 不同! 但是这个缓存程序还会多一个 PPID 的参数,PPID 如前所述,就是父程序的程序识别码啦!然后(2)缓存程序开始以 exec 的方式加载实际要运行的程序,以上述图示来讲,新的程序名称为 qqq ,最终子程序的程序码就会变成 qqq 了! 这样了解乎!

 ----------------------------------------------------------------------
4.系统或网络服务:常驻在内存的程序

 如果就我们之前学到的一些命令数据来看,其实我们下达的命令都很简单,包括用 ls 显示文件啊、用 touch 创建文件啊、rm/mkdir/cp/mv 等命令管理文件啊、chmod/chown/passwd 等等的命令来管理权限等等的,不过, 这些命令都是运行完就结束了。也就是说,该项命令被触发后所产生的 PID 很快就会终止呢! 那有没有一直在运行的程序啊?当然有啊!而且多的是呢!

 

举个简单的例子来说好了,我们知道系统每分钟都会去扫瞄 /etc/crontab 以及相关的配置档, 来进行工作排程吧?那么那个工作排程是谁负责的?当然不是鸟哥啊! 呵呵!是 crond 这个程序所管理的,我们将他启动在背景当中一直持续不断的运行, 套句以前 DOS 年代常常说的一句话,那就是『常驻在内存当中的程序』啦!

 

常驻在内存当中的程序通常都是负责一些系统所提供的功能以服务使用者各项任务,因此这些常驻程序就会被我们称为:服务 (daemon)。系统的服务非常的多, 不过主要大致分成系统本身所需要的服务,例如刚刚提到的 crond 及 atd ,还有 syslog 等等的。还有一些则是负责网络连线的服务,例如 Apache, named, postfix, vsftpd... 等等的。这些网络服务比较有趣的地方,在於这些程序被运行后,他会启动一个可以负责网络监听的端口 (port) ,以提供外部用户端 (client) 的连线要求。

----------------------------------------------------------------------------------------------------------------------------------------------------------

1.2 Linux 的多人多工环境

我们现在知道了,其实在 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 介面下,我可不可以进行多个工作啊? 当然可以啦!可以『同时』进行喔!举例来说,我可以这样做:

在这一串命令中,重点在那个 & 的功能,他表示将 file1 这个文件复制为 file2 ,且放置於背景中运行, 也就是说运行这一个命令之后,在这一个终端介面仍然可以做其他的工作!而当这一个命令 (cp file1 file2) 运行完毕之后,系统将会在你的终端介面显示完成的消息!很便利喔!

  • 多人多工的系统资源分配问题考虑:

多人多工确实有很多的好处,但其实也有管理上的困扰,因为使用者越来越多, 将导致你管理上的困扰哩!另外,由於使用者日盛,当使用者达到一定的人数后, 通常你的机器便需要升级了,因为 CPU 的运算与 RAM 的大小可能就会不敷使用!

举个例子来说,鸟哥之前的网站管理的有点不太好,因为使用了一个很复杂的人数统计程序, 这个程序会一直去取用 mysql 数据库的数据,偏偏因为流量大,造成 MySQL 很忙碌。 在这样的情况下,当鸟哥要登陆去写网页数据,或者要去使用讨论区的资源时, 哇!慢的很!简直就是『龟速』啊!后来终於将这个程序停止不用了, 以自己写的一个小程序来取代,呵呵!这样才让 CPU 的负载 (loading) 整个降下来~ 用起来顺畅多了! ^_^


 2. 工作管理 (job control)

 这个工作管理 (job control) 是用在 bash 环境下的,也就是说:『当我们登陆系统取得 bash shell 之后,在单一终端机介面下同时进行多个工作的行为管理 』。举例来说,我们在登陆 bash 后, 想要一边复制文件、一边进行数据搜寻、一边进行编译,还可以一边进行 vi 程序撰写! 当然我们可以重复登陆那六个文字介面的终端机环境中,不过,能不能在一个 bash 内达成? 当然可以啊!就是使用 job control 啦! ^_^

----------------------------------------------------------------------------------------------------------------------------------------------------------

2.1 什么是工作管理

 从上面的说明当中,你应该要了解的是:『进行工作管理的行为中, 其实每个工作都是目前 bash 的子程序,亦即彼此之间是有相关性的。 我们无法以 job control 的方式由 tty1 的环境去管理 tty2 的 bash !』 这个概念请你得先创建起来,后续的范例介绍之后,你就会清楚的了解罗!

或许你会觉得很奇怪啊,既然我可以在六个终端介面登陆,那何必使用 job control 呢? 真是脱裤子放屁,多此一举啊!不要忘记了呢,我们可以在 /etc/security/limits.conf (第十四章) 里面配置使用者同时可以登陆的连线数,在这样的情况下,某些使用者可能仅能以一个连线来工作呢! 所以罗,你就得要了解一下这种工作管理的模式了!此外,这个章节内容也会牵涉到很多的数据流重导向,所以,如果忘记的话, 务必回到第十一章 BASH Shell 看一看喔!

 

由於假设我们只有一个终端介面,因此在可以出现提示字节让你操作的环境就称为前景 (foreground),至於其他工作就可以让你放入背景 (background) 去暂停或运行。要注意的是,放入背景的工作想要运行时, 他必须不能够与使用者互动。举例来说, vim 绝对不可能在背景里面运行 (running) 的!因为你没有输入数据他就不会跑啊! 而且放入背景的工作是不可以使用 [ctrl]+c 来终止的』!

总之,要进行 bash 的 job control 必须要注意到的限制是:

  • 这些工作所触发的程序必须来自於你 shell 的子程序(只管理自己的 bash);
  • 前景:你可以控制与下达命令的这个环境称为前景的工作 (foreground);
  • 背景:可以自行运行的工作,你无法使用 [ctrl]+c 终止他,可使用 bg/fg 呼叫该工作;
  • 背景中『运行』的程序不能等待 terminal/shell 的输入(input)

----------------------------------------------------------------------------------------------------------------------------------------------------------

2.2 job control 的管理:&, [ctrl]-z, jobs, fg, bg, kill

bash 只能够管理自己的工作而不能管理其他 bash 的工作,所以即使你是 root 也不能够将别人的 bash 底下的 job 给他拿过来运行。此外,又分前景与背景,然后在背景里面的工作状态又可以分为『暂停 (stop)』与『运行中 (running)』。那实际进行 job 控制的命令有哪些? 

 

1.直接将命令丢到背景中『运行』的 &
如同前面提到的,我们在只有一个 bash 的环境下,如果想要同时进行多个工作, 那么可以将某些工作直接丢到背景环境当中,让我们可以继续操作前景的工作!那么如何将工作丢到背景中? 最简单的方法就是利用『 & 』这个玩意儿了!举个简单的例子,我们要将 /etc/ 整个备份成为 /tmp/etc.tar.gz 且不想要等待,那么可以这样做

[root@www ~]# tar -zpcf /tmp/etc.tar.gz /etc &
[1] 8400  <== [job number] PID 
[root@www ~]# tar: Removing leading `/\' from member names 
# 在中括号内的号码为工作号码 (job number),该号码与 bash 的控制有关。
# 后续的 8400 则是这个工作在系统中的 PID。至於后续出现的数据是 tar 运行的数据流,
# 由於我们没有加上数据流重导向,所以会影响画面!不过不会影响前景的操作喔!

仔细的瞧一瞧,我在输入一个命令后,在该命令的最后面加上一个『 & 』代表将该命令丢到背景中, 此时 bash 会给予这个命令一个『工作号码(job number)』,就是那个 [1] 啦!至於后面那个 8400 则是该命令所触发的『 PID 』了!而且,有趣的是,我们可以继续操作 bash 呢!很不赖吧! 不过,那么丢到背景中的工作什么时候完成?完成的时候会显示什么?如果你输入几个命令后,突然出现这个数据:

就代表 [1] 这个工作已经完成 (Done) ,该工作的命令则是接在后面那一串命令列。 这样了解了吧!另外,这个 & 代表:『将工作丢到背景中去运行』喔! 注意到那个『运行』的字眼!此外,这样的情况最大的好处是: 不怕被 [ctrl]+c 中断的啦! 此外,将工作丢到背景当中要特别注意数据的流向喔!包括上面的信息就有出现错误信息,导致我的前景被影响。 虽然只要按下 [enter] 就会出现提示字节。但如果我将刚刚那个命令改成:

 

情况会怎样?在背景当中运行的命令,如果有 stdout 及 stderr 时,他的数据依旧是输出到萤幕上面的, 所以,我们会无法看到提示字节,当然也就无法完好的掌握前景工作。同时由於是背景工作的 tar , 此时你怎么按下 [ctrl]+c 也无法停止萤幕被搞的花花绿绿的!所以罗,最佳的状况就是利用数据流重导向, 将输出数据传送至某个文件中。举例来说,我可以这样做

 

[root@www ~]# tar -zpcvf /tmp/etc.tar.gz /etc > /tmp/log.txt 2>&1 &
[1] 8429
[root@www ~]#

呵呵!如此一来,输出的资讯都给他传送到 /tmp/log.txt 当中,当然就不会影响到我们前景的作业了。 这样说,您应该可以更清楚数据流重导向的重要性了吧!^_^

Tips:
工作号码 (job number) 只与你这个 bash 环境有关,但是他既然是个命令触发的咚咚,所以当然一定是一个程序, 因此你会观察到有 job number 也搭配一个 PID !


2.将『目前』的工作丢到背景中『暂停』:[ctrl]-z
想个情况:如果我正在使用 vi ,却发现我有个文件不知道放在哪里,需要到 bash 环境下进行搜寻,此时是否要结束 vi 呢?呵呵!当然不需要啊!只要暂时将 vi 给他丢到背景当中等待即可。 例如以下的案例:

[root@www ~]# vi ~/.bashrc
# 在 vi 的一般模式下,按下 [ctrl]-z 这两个按键
[1]+  Stopped                 vim ~/.bashrc
[root@www ~]#   <==顺利取得了前景的操控权!
[root@www ~]# find / -print
....(输出省略)....
# 此时萤幕会非常的忙碌!因为萤幕上会显示所有的档名。请按下 [ctrl]-z 暂停
[2]+  Stopped                 find / -print

在 vi 的一般模式下,按下 [ctrl] 及 z 这两个按键,萤幕上会出现 [1] ,表示这是第一个工作, 而那个 + 代表最近一个被丢进背景的工作,且目前在背景下默认会被取用的那个工作 (与 fg 这个命令有关 )!而那个 Stopped 则代表目前这个工作的状态。在默认的情况下,使用 [ctrl]-z 丢到背景当中的工作都是『暂停』的状态喔!


3.观察目前的背景工作状态: jobs

[root@www ~]# jobs [-lrs]
选项与参数:
-l  :除了列出 job number 与命令串之外,同时列出 PID 的号码;
-r  :仅列出正在背景 run 的工作;
-s  :仅列出正在背景当中暂停 (stop) 的工作。

范例一:观察目前的 bash 当中,所有的工作,与对应的 PID
[root@www ~]# jobs -l
[1]- 10314 Stopped                 vim ~/.bashrc
[2]+ 10833 Stopped                 find / -print

如果想要知道目前有多少的工作在背景当中,就用 jobs 这个命令吧!一般来说,直接下达 jobs 即可! 不过,如果你还想要知道该 job number 的 PID 号码,可以加上 -l 这个参数啦! 在输出的资讯当中,例如上表,仔细看到那个 + - 号喔!那个 + 代表默认的取用工作。 所以说:『目前我有两个工作在背景当中,两个工作都是暂停的, 而如果我仅输入 fg 时,那么那个 [2] 会被拿到前景当中来处理』

 

其实 + 代表最近被放到背景的工作号码, - 代表最近最后第二个被放置到背景中的工作号码。 而超过最后第三个以后的工作,就不会有 +/- 符号存在了!


4.将背景工作拿到前景来处理:fg

刚刚提到的都是将工作丢到背景当中去运行的,那么有没有可以将背景工作拿到前景来处理的? 有啊!就是那个 fg (foreground) 啦!举例来说,我们想要将上头范例当中的工作拿出来处理时:

[root@www ~]# fg %jobnumber
选项与参数:
%jobnumber :jobnumber 为工作号码(数字)。注意,那个 % 是可有可无的!

范例一:先以 jobs 观察工作,再将工作取出:
[root@www ~]# jobs
[1]- 10314 Stopped                 vim ~/.bashrc
[2]+ 10833 Stopped                 find / -print
[root@www ~]# fg      <==默认取出那个 + 的工作,亦即 [2]。立即按下[ctrl]-z
[root@www ~]# fg %1   <==直接规定取出的那个工作号码!再按下[ctrl]-z
[root@www ~]# jobs
[1]+  Stopped                 vim ~/.bashrc
[2]-  Stopped                 find / -print

经过 fg 命令就能够将背景工作拿到前景来处理罗!不过比较有趣的是最后一个显示的结果,我们会发现 + 出现在第一个工作后! 怎么会这样啊?这是因为你刚刚利用 fg %1 将第一号工作捉到前景后又放回背景,此时最后一个被放入背景的将变成 vi 那个命令动作, 所以当然 [1] 后面就


5.让工作在背景下的状态变成运行中: bg
我们刚刚提到,那个 [ctrl]-z 可以将目前的工作丢到背景底下去『暂停』, 那么如何让一个工作在背景底下『 Run 』呢?我们可以在底下这个案例当中来测试! 注意喔!底下的测试要进行的快一点!^_^

范例一:一运行 find / -perm +7000 > /tmp/text.txt 后,立刻丢到背景去暂停!
[root@www ~]# find / -perm +7000 > /tmp/text.txt
# 此时,请立刻按下 [ctrl]-z 暂停!
[3]+  Stopped                 find / -perm +7000 > /tmp/text.txt

范例二:让该工作在背景下进行,并且观察他!!
[root@www ~]# jobs ; bg %3 ; jobs
[1]-  Stopped                 vim ~/.bashrc
[2]   Stopped                 find / -print
[3]+  Stopped                 find / -perm +7000 > /tmp/text.txt
[3]+ find / -perm +7000 > /tmp/text.txt &  <==用 bg%3 的情况!
[1]+  Stopped                 vim ~/.bashrc
[2]   Stopped                 find / -print
[3]-  Running                 find / -perm +7000 > /tmp/text.txt &

看到哪里有差异吗?呼呼!没错!就是那个状态列~以经由 Stopping 变成了 Running 罗! 看到差异点,嘿嘿!命令列最后方多了一个 & 的符号罗! 代表该工作被启动在背景当中了啦! ^_^


6.管理背景当中的工作: kill
刚刚我们可以让一个已经在背景当中的工作继续工作,也可以让该工作以 fg 拿到前景来, 那么,如果想要将该工作直接移除呢?或者是将该工作重新启动呢?这个时候就得需要给予该工作一个讯号 (signal) ,让他知道该怎么作才好啊!此时, kill 这个命令就派上用场啦

[root@www ~]# kill -signal %jobnumber
[root@www ~]# kill -l
选项与参数:
-l  :这个是 L 的小写,列出目前 kill 能够使用的讯号 (signal) 有哪些?
signal :代表给予后面接的那个工作什么样的指示罗!用 man 7 signal 可知:
  -1 :重新读取一次参数的配置档 (类似 reload);
  -2 :代表与由键盘输入 [ctrl]-c 同样的动作;
  -9 :立刻强制删除一个工作;
  -15:以正常的程序方式终止一项工作。与 -9 是不一样的。

范例一:找出目前的 bash 环境下的背景工作,并将该工作『强制删除』。
[root@www ~]# jobs
[1]+  Stopped                 vim ~/.bashrc
[2]   Stopped                 find / -print
[root@www ~]# kill -9 %2; jobs
[1]+  Stopped                 vim ~/.bashrc
[2]   Killed                  find / -print
# 再过几秒你再下达 jobs 一次,就会发现 2 号工作不见了!因为被移除了!

范例:找出目前的 bash 环境下的背景工作,并将该工作『正常终止』掉。
[root@www ~]# jobs
[1]+  Stopped                 vim ~/.bashrc
[root@www ~]# kill -SIGTERM %1
# -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的小写)!

另外, kill 后面接的数字默认会是 PID如果想要管理 bash 的工作控制,就得要加上 %数字 了, 这点也得特别留意才行喔!

----------------------------------------------------------------------------------------------------------------------------------------------------------

2.3 离线管理问题: nohup

要注意的是,我们在工作管理当中提到的『背景』指的是在终端机模式下可以避免 [crtl]-c 中断的一个情境, 并不是放到系统的背景去喔!所以工作管理的背景依旧与终端机有关啦! 在这样的情况下,如果你是以远程连线方式连接到你的 Linux 主机,并且将工作以 & 的方式放到背景去, 请问,在工作尚未结束的情况下你离线了,该工作还会继续进行吗?答案是『否』!不会继续进行,而是会被中断掉。


 3. 程序管理

 

本章一开始就提到所谓的『程序』的概念,包括程序的触发、子程序与父程序的相关性等等, 此外,还有那个『程序的相依性』以及所谓的『僵尸程序』等等需要说明的呢!为什么程序管理这么重要呢?这是因为:

  • 首先,本章一开始就谈到的,我们在操作系统时的各项工作其实都是经过某个 PID 来达成的 (包括你的 bash 环境), 因此,能不能进行某项工作,就与该程序的权限有关了。
  • 再来,如果您的 Linux 系统是个很忙碌的系统,那么当整个系统资源快要被使用光时, 您是否能够找出最耗系统的那个程序,然后删除该程序,让系统恢复正常呢?
  • 此外,如果由於某个程序写的不好,导致产生一个有问题的程序在内存当中,您又该如何找出他,然后将他移除呢?
  • 如果同时有五六项工作在您的系统当中运行,但其中有一项工作才是最重要的, 该如何让那一项重要的工作被最优先运行呢?

所以罗,一个称职的系统管理员,必须要熟悉程序的管理流程才行,否则当系统发生问题时,还真是很难解决问题呢! 底下我们会先介绍如何观察程序与程序的状态,然后再加以程序控制罗!

----------------------------------------------------------------------------------------------------------------------------------------------------------

3.1 程序的观察: ps (ps -l, ps aux, zombie), top, pstree

 既然程序这么重要,那么我们如何查阅系统上面正在运行当中的程序呢?很简单啊! 利用静态的 ps 或者是动态的 top,还能以 pstree 来查阅程序树之间的关系喔

 

1.ps :将某个时间点的程序运行情况撷取下来

[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  :做一个更为完整的输出。

鸟哥个人认为 ps 这个命令的 man page 不是很好查阅,因为很多不同的 Unix 都使用这个 ps 来查阅程序状态, 为了要符合不同版本的需求,所以这个 man page 写的非常的庞大!因此,通常鸟哥都会建议你,直接背两个比较不同的选项

 一个是只能查阅自己 bash 程序的『 ps -l 』一个则是可以查阅所有系统运行的程序『 ps aux 』!注意,你没看错,是『 ps aux 』没有那个减号 (-) !先来看看关於自己 bash 程序状态的观察:

 

1.1仅观察自己的 bash 相关程序: ps -l

范例一:将目前属於您自己这次登陆的 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 秀出来的数据有哪些呢? 我们就来观察看看:

F:代表这个程序旗标 (process flags),说明这个程序的总结权限,常见号码有:
若为 4 表示此程序的权限为 root ;
若为 1 则表示此子程序仅进行复制(fork)而没有实际运行(exec)。

S:代表这个程序的状态 (STAT),主要的状态有:
R (Running):该程序正在运行中;
S (Sleep):该程序目前正在睡眠状态(idle),但可以被唤醒(signal)。
D :不可被唤醒的睡眠状态,通常这支程序可能在等待 I/O 的情况(ex>列印)
T :停止状态(stop),可能是在工作控制(背景暂停)或除错 (traced) 状态;
Z (Zombie):僵尸状态,程序已经终止但却无法被移除至内存外。

UID/PID/PPID:代表『此程序被该 UID 所拥有/程序的 PID 号码/此程序的父程序 PID 号码』

C:代表 CPU 使用率,单位为百分比;

PRI/NI:Priority/Nice 的缩写,代表此程序被 CPU 所运行的优先顺序,数值越小代表该程序越快被 CPU 运行。详细的 PRI 与 NI 将在下一小节说明。

ADDR/SZ/WCHAN:都与内存有关,ADDR 是 kernel function,指出该程序在内存的哪个部分,如果是个 running 的程序,一般就会显示『 - 』 / SZ 代表此程序用掉多少内存 / WCHAN 表示目前程序是否运行中,同样的, 若为 - 表示正在运行中。

TTY:登陆者的终端机位置,若为远程登陆则使用动态终端介面 (pts/n);

TIME:使用掉的 CPU 时间,注意,是此程序实际花费 CPU 运行的时间,而不是系统时间;

CMD:就是 command 的缩写,造成此程序的触发程序之命令为何。
所以你看到的 ps -l 输出信息中,他说明的是:『bash 的程序属於 UID 为 0 的使用者,状态为睡眠 (sleep), 之所以为睡眠因为他触发了 ps (状态为 run) 之故。此程序的 PID 为 13639,优先运行顺序为 75 , 下达 bash 所取得的终端介面为 pts/1 ,运行状态为等待 (wait) 。』这样已经够清楚了吧? 您自己尝试解析一下那么 ps 那一行代表的意义为何呢? ^_^

接下来让我们使用 ps 来观察一下系统内所有的程序状态吧!

 

1.2.观察系统所有程序: ps aux

范例二:列出目前所有的正在内存当中的程序:
[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
USER:该 process 属於那个使用者帐号的?
PID :该 process 的程序识别码。
%CPU:该 process 使用掉的 CPU 资源百分比;
%MEM:该 process 所占用的实体内存百分比;
VSZ :该 process 使用掉的虚拟内存量 (Kbytes)
RSS :该 process 占用的固定的内存量 (Kbytes)
TTY :该 process 是在那个终端机上面运行,若与终端机无关则显示 ?,另外, tty1-tty6 是本机上面的登陆者程序,若为 pts/0 等等的,则表示为由网络连接进主机的程序。
STAT:该程序目前的状态,状态显示与 ps -l 的 S 旗标相同 (R/S/T/Z)
START:该 process 被触发启动的时间;
TIME :该 process 实际使用 CPU 运行的时间。
COMMAND:该程序的实际命令为何?

一般来说,ps aux 会依照 PID 的顺序来排序显示,我们还是以 13639 那个 PID 那行来说明!该行的意义为『 root 运行的 bash PID 为 13639,占用了 0.2% 的内存容量百分比,状态为休眠 (S),该程序启动的时间为 11:44 , 且取得的终端机环境为 pts/1 。』与 ps aux 看到的其实是同一个程序啦!这样可以理解吗? 让我们继续使用 ps 来观察一下其他的资讯吧!

 

 1.3 其他

 

范例三:以范例一的显示内容,显示出所有的程序:
[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 读构建之法第十七章有感(作业四)

Week4-作业1:《构建之法》第四章第十七章 阅读笔记与思考

谈谈我对构建之法第四章与第十七章的理解

第四章与第十七章阅读有感

《构建之法》读第十七章收获

读《构建之法》第四章 第十七章