进程管理与SELinux初探 (16 章)

1、进程

在 Linux 系统当中:“触发任何一个事件时,系统都会将他定义成为一个程序,并且给予这个程序一个 ID ,称为 PID,同时依据启发这个程序的使用者与相关属性关系,给予这个 PID 一组有效的权限设置

1.1 进程与程序

执行一个程序或命令就可以触发一个事件从而获取一个PID;

程序与程序作个总结:

  • 程序 (program):通常为 binary program ,放置在储存媒体中 (如硬盘、光盘、软盘、磁带等), 为实体文件的型态存在;
  • 进程 (process):程序被触发后,执行者的权限与属性、程序的程序码与所需数据等都会被载入内存中, 操作系统并给予这个内存内的单元一个识别码 (PID),可以说,程序就是一个正在运行中的程序。

子进程与父进程:

 

 范例一:请在目前的 bash 环境下,再触发一次 bash ,并以“ ps -l ”这个指令观察程序相关的输出信息。答:直接执行 bash ,会进入到子程序的环境中,然后输入 ps -l 后,出现:

[root@localhost ~]# bash
[root@localhost ~]# ps -l
F S   UID    PID   PPID  C PRI  NI ADDR SZ WCHAN  TTY          TIME CMD
4 S     0  10366  10124  0  80   0 - 48520 do_wai pts/1    00:00:00 su
4 S     0  10370  10366  0  80   0 - 29082 do_wai pts/1    00:00:00 bash
4 S     0  10699  10370  0  80   0 - 29143 do_wai pts/1    00:00:00 bash
0 R     0  10733  10699  0  80   0 - 38331 -      pts/1    00:00:00 ps

fork and exec:程序调用的流程

Linux 的程序调用通常称为 fork-and-exec 的流程;

程序都会借由父程序以复制 (fork) 的方式产生一个一模一样的子程序, 然后被复制出来的子程序再以 exec 的方式来执行实际要进行的程序,最终就成为一个子程序的存在。 整个流程有点像下面这张图:

(1)系统先以 fork 的方式复制一个与父程序相同的暂存程序,这个程序与父程序唯一的差别就是 PID 不同! 但是这个暂存程序还会多一个 PPID 的参数,PPID 如前所述,就是父程序的程序识别码啦!然后

(2)暂存程序开始以 exec 的方式载入实际要执行的程序,以上述图示来讲,新的程序名称为 qqq ,最终子程序的程序码就会变成 qqq 了 

1.2 Linux 的多用户多任务环境

在单一的 bash 接口下,可以进行多个工作,举例来说,我可以这样做

[root@study ~]# cp file1 file2 &

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

2  工作管理Job Control

2.1 工作管理

执行任务管理的操作中, 其实每个任务都是目前 bash 的子程序,亦即彼此之间是有相关性的。 我们无法以 job control 的方式由 tty1 的环境去管理 tty2 的 bash;

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

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

2.2 job control 的管理

实际进行 job 控制的指令如下:

2.2.1 直接将指令丢到背景中“执行”的 &;

在指令的最后面加上一个“ & ”代表将该指令丢到后台中执行

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

后台工作完成后会显示:

[1]+  Done                    tar -zpcf /tmp/etc.tar.gz /etc

将输出数据重定向到某个文件中:

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

2.2.2 [ctrl]-z:将【目前】的任务丢到后台【暂停】

若正在使用 vim ,发现有个文件不知放在哪里,需要到 bash 环境下进行搜寻,此时可以选择不结束 vim ,只要暂时将 vim 给他丢到后台当中等待即可。

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

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

2.2.3 jobs查看目前的后台任务状态

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

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

+ 代表默认的取用工作 所以说:“目前我有两个工作在后台当中,两个工作都是暂停的, 而如果我仅输入 fg 时,那么那个 [2] 会被拿到前景当中来处理”!

+ 代表最近被放到后台的任务号码, - 代表最近的前一个(首先)被放置到后台中的任务号码。 而超过最后第三个以后的工作,就不会有 +/- 符号存在了!

2.2.4  fg:将后台工作拿到前台来处理

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

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

[1]+  已停止               vim ~/.bashrc
[root@localhost ~]# jobs
[1]+  已停止               vim ~/.bashrc
[2]-  已停止               find / -print

2.2.5 bg:让任务在后台下的状态变成运行中

#范例一:一执行 find / -perm /7000 > /tmp/text.txt 后,立刻丢到背景去暂停!
[root@localhost ~]# find / -perm /7000 > /tmp/text.txt
^Z    # 此时,请立刻按下 [ctrl]-z 暂停!
[3]+  已停止               find / -perm /7000 > /tmp/text.txt
#范例二:让该工作在背景下进行,并且观察他!!
[root@localhost ~]# jobs;bg %3;jobs
[1]-  已停止               vim ~/.bashrc
[2]   已停止               find / -print
[3]+  已停止               find / -perm /7000 > /tmp/text.txt
[3]+ find / -perm /7000 > /tmp/text.txt &
[1]+  已停止               vim ~/.bashrc
[2]   已停止               find / -print
[3]-  运行中               find / -perm /7000 > /tmp/text.txt &

2.2.6 kill:管理后台当中的工作

[root@localhost ~]# kill -signal %jobnumber
[root@localhost ~]# kill -l
选项与参数:
-l  :这个是 L 的小写,列出目前 kill 能够使用的讯号 (signal) 有哪些?
signal :代表给予后面接的那个工作什么样的指示啰!用 man 7 signal 可知:
  -1 :重新读取一次参数的配置文件 (类似 reload);
  -2 :代表与由键盘输入 [ctrl]-c 同样的动作;
  -9 :立刻强制删除一个工作;
  -15:以正常的程序方式终止一项工作。与 -9 是不一样的。
//范例一:找出目前的 bash 环境下的背景工作,并将该工作“强制删除”。
[root@localhost ~]# jobs
[1]+  已停止               vim ~/.bashrc
[2]   已停止               find / -print
[root@localhost ~]# kill -9 %2; jobs
[1]+  已停止               vim ~/.bashrc
[2]   已杀死               find / -print
# 再过几秒你再下达 jobs 一次,就会发现 2 号工作不见了!因为被移除了!
//范例二:找出目前的 bash 环境下的背景工作,并将该工作“正常终止”掉。
[root@localhost ~]# kill -SIGTERM %1

[1]+  已停止               vim ~/.bashrc

# -SIGTERM 与 -15 是一样的!您可以使用 kill -l 来查阅!
# 不过在这个案例中, vim 的工作无法被结束喔!因为他无法通过 kill 正常终止的意思!

2.3 脱机(离线)管理问题nohup

后台”指的是在终端机模式下可以避免 [crtl]-c 中断的一个情境, 可以说那个是 bash 的后台,并不是放到系统的背景去;

nohup 可以让你在离线或登出系统后,还能够让工作继续进行

[root@study ~]# nohup [指令与参数]   <==在终端机前景中工作
[root@study ~]# nohup [指令与参数] & <==在终端机背景中工作
# 1\. 先编辑一支会“睡着 500 秒”的程序:
[root@study ~]# vim sleep500.sh
#!/bin/bash
/bin/sleep 500s
/bin/echo "I have slept 500 seconds."

# 2\. 丢到后台中去执行,并且立刻登出系统:
[root@study ~]# chmod a+x sleep500.sh   #事先不知道sleep500.sh权限,只是想给每个人增加可执行权限 chmod a+x sleep500.sh
[root@study ~]# nohup ./sleep500.sh &
[2] 14812
[root@study ~]#  nohup: ignoring input and appending output to `nohup.out' <==会告知这个讯息!
[root@study ~]# exit
  • 如果你再次登陆的话,再使用 pstree 去查阅你的程序,会发现 sleep500.sh 还在执行中
  • 如果你想要让在背景的工作在你登出后还能够继续的执行,那么使用 nohup 搭配 & 是不错的运行情境

3 进程管理

3.1 ps/top/pstree查看进程

3.1.1 ps

[root@study ~]# ps aux  <==观察系统所有的进程
[root@study ~]# ps -lA  <==也是能够观察所有系统的进程
[root@study ~]# ps axjf <==连同部分进程树状态
#选项与参数:
-A  :所有的进程均显示出来,与 -e 具有同样的效果;
-a  :不显示与终端有关的所有进程;
-u  :有效使用者 (effective user) 相关的进程 ;
x   :通常与 a 这个参数一起使用,可列出较完整信息。
#输出格式规划:
l   :较长、较详细的将该 PID 的的信息列出;
j   :任务的格式 (jobs format)
-f  :做一个更为完整的输出。

重点记住查阅自己 bash 进程的“ ps -l ”和查阅所有系统运行的进程命令“ ps aux

#范例一:将目前属于您自己这次登陆的 PID 与相关信息列示出来(只与自己的 bash 有关)
[root@localhost ~]# ps -l
F S   UID    PID   PPID  C PRI  NI ADDR SZ WCHAN  TTY          TIME CMD
4 S     0  10366  10124  0  80   0 - 48520 do_wai pts/1    00:00:00 su
4 S     0  10370  10366  0  80   0 - 29082 do_wai pts/1    00:00:00 bash
4 S     0  10699  10370  0  80   0 - 29163 do_wai pts/1    00:00:00 bash
0 R     0  25778  10699  0  80   0 - 38331 -      pts/1    00:00:00 ps
  • 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 的缩写,造成此程序的触发程序之指令为何。

3.1.2 ps aux:观察系统所有进程

#范例二:列出目前所有的正在内存当中的进程:
[mcb@localhost ~]$ ps aux
USER        PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root          1  0.0  0.5 194092  5164 ?        Ss   7月03   0:07 /usr/lib/systemd/systemd --switched-root --system --deseria
root          2  0.0  0.0      0     0 ?        S    7月03   0:00 [kthreadd]
root          4  0.0  0.0      0     0 ?        S<   7月03   0:00 [kworker/0:0H]
...(中间省略)...
mcb        2091  0.0  0.5 465100  5724 ?        Sl   7月03   0:00 /usr/libexec/ibus-x11 --kill-daemon
mcb        2094  0.0  0.1 376180  1500 ?        Sl   7月03   0:00 /usr/libexec/ibus-portal
mcb        2103  0.0  0.1 364920  1080 ?        Sl   7月03   0:00 /usr/libexec/xdg-permission-store
...(中间省略)...
mcb       27721  0.0  0.1 155448  1864 pts/0    R+   09:46   0:00 ps aux
  • %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:该程序的实际指令为何?
范例三:找出与 cron 与 rsyslog 这两个服务有关的 PID 号码?
[root@localhost ~]# ps aux | egrep -n 'cron|rsyslog'
99:root       1117  0.0  0.1 220656  1984 ?        Ssl  7月03   0:02 /usr/sbin/rsyslogd -n
103:root       1143  0.0  0.1 126420  1132 ?        Ss   7月03   0:01 /usr/sbin/crond -n
203:root      28675  0.0  0.0 123360   760 ?        Ss   10:01   0:00 /usr/sbin/anacron -s
207:root      28885  0.0  0.0 112828   984 pts/0    R+   10:04   0:00 grep -E --color=auto -n cron|rsyslog

3.1.3 top:动态查看进程的变化

top可以持续监测进程运行状态,而ps则是选取一个时间点的进程状态

[root@study ~]# 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@localhost ~]# top -d 2
top - 10:19:22 up 16:19,  3 users,  load average: 0.00, 0.01, 0.05
Tasks: 205 total,   1 running, 204 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,  0.0 st
KiB Mem :   995676 total,    86688 free,   711704 used,   197284 buff/cache
KiB Swap:  2097148 total,  2024188 free,    72960 used.   106128 avail Mem
<==如果加入 k 或 r 时,就会有相关的字样出现在这里
   PID USER      PR  NI    VIRT    RES    SHR S %CPU %MEM     TIME+ COMMAND
   291 root      20   0       0      0      0 S  0.5  0.0   0:15.70 xfsaild/sda3
 29757 root      20   0  162100   2368   1600 R  0.5  0.2   0:00.13 top
     1 root      20   0  194092   5212   2704 S  0.0  0.5   0:07.82 systemd
     2 root      20   0       0      0      0 S  0.0  0.0   0:00.03 kthreadd
     4 root       0 -20       0      0      0 S  0.0  0.0   0:00.00 kworker/0:0H
     6 root      20   0       0      0      0 S  0.0  0.0   0:00.77 ksoftirqd/0

如果你想要使用内存使用率排序,则可以按下【M】, 若要回复则按下【P】即可。如果想要离开 top 则按下【q】

#范例二:我们自己的 bash PID 可由 $$ 变量取得,请使用 top 持续观察该 PID
[root@localhost ~]# echo $$
27971
[root@localhost ~]# top -d 2 -p 27971
top - 10:46:17 up 16:46,  3 users,  load average: 0.00, 0.01, 0.05
Tasks:   1 total,   0 running,   1 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
KiB Mem :   995676 total,    86144 free,   711236 used,   198296 buff/cache
KiB Swap:  2097148 total,  2024188 free,    72960 used.   106092 avail Mem

   PID USER      PR  NI    VIRT    RES    SHR S %CPU %MEM     TIME+ COMMAND
 27971 root      20   0  116460   2920   1660 S  0.0  0.3   0:00.04 bash

3.1.4 pstree

[root@localhost ~]# pstree [-A|U] [-up]
选项与参数:
-A  :各程序树之间的连接以 ASCII 字符来连接;
-U  :各程序树之间的连接以万国码的字符来连接。在某些终端接口下可能会有错误;
-p  :并同时列出每个 process 的 PID;
-u  :并同时列出每个 process 的所属帐号名称。

范例一:列出目前系统上面所有的程序树的相关性:
[root@study ~]# pstree -A
systemd-+-ModemManager---2*[{ModemManager}]       # 这行是 ModenManager 与其子程序
        &#124;-NetworkManager---3*[{NetworkManager}]   # 前面有数字,代表子程序的数量!
....(中间省略)....
        &#124;-sshd---sshd---sshd---bash---bash---sudo---su---bash---pstree <==我们指令执行的相依性
....(下面省略)....
# 注意一下,为了节省版面,所以鸟哥已经删去很多程序了!

范例二:承上题,同时秀出 PID 与 users
[root@study ~]# pstree -Aup
systemd(1)-+-ModemManager(745)-+-{ModemManager}(785)
           &#124;                   `-{ModemManager}(790)
           &#124;-NetworkManager(870)-+-{NetworkManager}(907)
           &#124;                     &#124;-{NetworkManager}(911)
           &#124;                     `-{NetworkManager}(914)
....(中间省略)....
           &#124;-sshd(1326)---sshd(13923)---sshd(13927,dmtsai)---bash(13928)---bash(13970)---
....(下面省略)....
# 在括号 () 内的即是 PID 以及该程序的 owner 喔!一般来说,如果该程序的所有人与父程序同,
# 就不会列出,但是如果与父程序不一样,那就会列出该程序的拥有者!看上面 13927 就转变成 dmtsai 了
范例一:列出目前系统上面所有的程序树的相关性:
[root@localhost ~]# pstree -A
systemd-+-ModemManager---2*[{ModemManager}]
        |-NetworkManager-+-dhclient
        |                `-2*[{NetworkManager}]
....(中间省略)....
 |-gdm-+-X---{X}
        |     |-gdm-session-wor-+-gnome-session-b-+-abrt-ap+
        |     |                 |                 |-gnome-s+
....(下面省略)....
范例二:承上题,同时秀出 PID 与 users
[root@localhost ~]# pstree -Aup
systemd(1)-+-ModemManager(593)-+-{ModemManager}(606)
           |                   `-{ModemManager}(624)
           |-NetworkManager(793)-+-dhclient(27255)
           |                     |-{NetworkManager}(798)
           |                     `-{NetworkManager}(802)
....(中间省略)....
  |-gdm(1141)-+-X(1281)---{X}(1430)
           |           |-gdm-session-wor(1829)-+-gnome-session-b(1862,mcb)-+-abrt-applet(2387)-+-{abrt-applet}(2398)
           |           |                       |                           |                   `-{abrt-applet}(2400)
           |           |                       |                           |-gnome-shell(2057)-+-ibus-daemon(2082)-+-ibus-dco+
....(下面省略)....

由 pstree 的输出我们也可以很清楚的知道,所有的程序都是依附在 systemd 这支程序下面的! 仔细看一下,这支程序的 PID 是一号!因为他是由 Linux 核心所主动调用的第一支程序!所以 PID 就是一号了;

3.2 进程的管理

主要的信号代号与名称对应及内容是

代号名称内容
1SIGHUP启动被终止的程序,可让该 PID 重新读取自己的配置文件,类似重新启动
2SIGINT相当于用键盘输入 [ctrl]-c 来中断一个程序的进行
9SIGKILL代表强制中断一个程序的进行,如果该程序进行到一半, 那么尚未完成的部分可能会有“半产品”产生,类似 vim会有 .filename.swp 保留下来。
15SIGTERM以正常的结束程序来终止该程序。由于是正常的终止, 所以后续的动作会将他完成。不过,如果该程序已经发生问题,就是无法使用正常的方法终止时, 输入这个 signal 也是没有用的。
19SIGSTOP相当于用键盘输入 [ctrl]-z 来暂停一个程序的进行

3.2.1 kill -signal PID

kill 后面直接加数字与加上 %number 的情况是不同的;

例题:以 ps 找出 rsyslogd 这个程序的 PID 后,再使用 kill 传送讯息,使得 rsyslogd 可以重新读取配置文件。

答:由于需要重新读取配置文件,因此 signal 是 1 号。至于找出 rsyslogd 的 PID 可以是这样做:

ps aux | grep 'rsyslogd' | grep -v 'grep'| awk '{print $2}'

接下来则是实际使用 kill -1 PID,因此,整串指令会是这样:

 kill -SIGHUP $(ps aux | grep 'rsyslogd' | grep -v 'grep'| awk '{print $2}')

如果要确认有没有重新启动 syslog ,可以参考登录文件的内容,使用如下指令查阅:

tail -5 /var/log/messages

如果你有看到类似“Aug 5 01:25:02 study rsyslogd: [origin software="rsyslogd" swVersion="7.4.7" x-pid="742" x-info="The rocket-fast Syslog Server - rsyslog"] rsyslogd was HUPed”之类的字样,就是表示 rsyslogd 在 8/5 有重新启动 (restart) 过了!

3.2.2 killall -signal 命令名称

killall是利用【执行命令的名称】来给予信号,而kill则是利用执行命令的PID来给予信号,这是二者最大的不同;

[root@localhost ~]# killall [-iIe] [command name]
选项与参数:
-i  :interactive 的意思,互动式的,若需要删除时,会出现提示字符给使用者;
-e  :exact 的意思,表示“后面接的 command name 要一致”,但整个完整的指令
      不能超过 15 个字符。
-I  :指令名称(可能含参数)忽略大小写。

//范例一:给予 rsyslogd 这个命令启动的 PID 一个 SIGHUP 的信号
[root@localhost ~]# killall -1 rsyslogd
//范例二:强制终止所有以 httpd 启动的程序 (其实并没有此程序在系统内)
[root@localhost ~]# killall -9 httpd
//范例三:依次询问每个 bash 程序是否需要被终止运行!
[root@localhost ~]# killall -i -9 bash
信号 bash(2632) ? (y/N) n
信号 bash(27338) ? (y/N) n
信号 bash(27971) ? (y/N) n
bash: no process found

3.3 进程的执行顺序

3.3.1 Priority和Nice值

无优先级的进程队列示意图

具有优先级的进程队列示意图

如上图所示,具高优先权的 pro1, pro2 可以被取用两次,而较不重要的 pro3, pro4 则运行次数较少。 如此一来 pro1, pro2 就可以较快被完成

PRI 值越低代表越优先。不过这个 PRI 值是由核心动态调整的, 使用者无法直接调整 PRI 值

可以通过调整nice值来调整进程的优先级,pri与nice的相关性如下:

PRI(new) = PRI(old) + nice
  • nice 值可调整的范围为 -20 ~ 19 ;
  • root 可随意调整自己或他人程序的 Nice 值,且范围为 -20 ~ 19 ;
  • 一般使用者仅可调整自己程序的 Nice 值,且范围仅为 0 ~ 19 (避免一般用户抢占系统资源);
  • 一般使用者仅可将 nice 值越调越高,例如本来 nice 为 5 ,则未来仅能调整到大于 5

修改nice值得办法:

  • 一开始执行程序就立即给予一个特定的 nice 值:用 nice 指令
  • 调整某个已经存在的 PID 的 nice 值:用 renice 指令

3.3.2 nice :新执行的命令即给予新的 nice 值

[root@localhost ~]# nice [-n 数字] command
选项与参数:
-n  :后面接一个数值,数值的范围 -20 ~ 19。

[root@localhost ~]# ps -l
F S   UID    PID   PPID  C PRI  NI ADDR SZ WCHAN  TTY          TIME CMD
4 S     0  27959  27338  0  80   0 - 48520 do_wai pts/0    00:00:00 su
4 S     0  27971  27959  0  80   0 - 29115 do_wai pts/0    00:00:00 bash
4 T     0  50414  27971  0  75  -5 - 36812 do_sig pts/0    00:00:00 vim
0 R     0  50452  27971  0  80   0 - 38331 -      pts/0    00:00:00 ps
# 原本的 bash PRI 为 80  ,所以 vim 默认应为 80。不过由于给予 nice  为 -5 ,
# 因此 vim 的 PRI 降低了!RPI 与 NI 各减 5 !但不一定每次都是正好相同!因为核心会动态调整
[root@localhost ~]# kill -9 %1     <==测试完毕将 vim 关闭

[1]+  已停止               nice -n -5 vim

3.3.3 renice :已存在进程的 nice 重新调整

[root@localhost ~]# renice [number] PID
选项与参数:
PID :某个程序的 ID !
#范例一:找出自己的 bash PID ,并将该 PID 的 nice 调整到 -5
[root@localhost ~]# ps -l
F S   UID    PID   PPID  C PRI  NI ADDR SZ WCHAN  TTY          TIME CMD
4 S     0  27959  27338  0  80   0 - 48520 do_wai pts/0    00:00:00 su
4 S     0  27971  27959  0  80   0 - 29166 do_wai pts/0    00:00:00 bash
0 R     0  51018  27971  0  80   0 - 38331 -      pts/0    00:00:00 ps
[root@localhost ~]# renice -5 27971
27971 (进程 ID) 旧优先级为 0,新优先级为 -5
[root@localhost ~]# ps -l
F S   UID    PID   PPID  C PRI  NI ADDR SZ WCHAN  TTY          TIME CMD
4 S     0  27959  27338  0  80   0 - 48520 do_wai pts/0    00:00:00 su
4 S     0  27971  27959  0  75  -5 - 29166 do_wai pts/0    00:00:00 bash
0 R     0  51541  27971  0  75  -5 - 38331 -      pts/0    00:00:00 ps

虽然修改的是 bash 那个程序,但是该程序所触发的 ps 指令当中的 nice 也会继承而为 -5 !整个 nice 值是可以在父程序 --> 子程序之间传递

3.4 查看系统资源信息

3.4.1 free :察看内存使用情况 P533

[root@localhost ~]# free [-b|-k|-m|-g|-h] [-t] [-s N -c N]
选项与参数:
-b  :直接输入 free 时,显示的单位是 KBytes,我们可以使用 b(Bytes), m(MBytes)
      k(KBytes), 及 g(GBytes) 来显示单位喔!也可以直接让系统自己指定单位 (-h)
-t  :在输出的最终结果,显示实体内存与 swap 的总量。
-s  :可以让系统每几秒钟输出一次,不间断的一直输出的意思!对于系统观察挺有效!
-c  :与 -s 同时处理~让 free 列出几次的意思~

范例一:显示目前系统的内存容量
[root@localhost ~]# free -m
              total        used        free      shared  buff/cache   available
Mem:            972         664          99          15         207         126
Swap:          2047          71        1976

3.4.2 uname:查看系统与内核相关信息 P533

uname 可以列出目前系统的内核版本、硬件架构以及 CPU 类型等信息。 

[root@localhost ~]# uname [-asrmpi]
选项与参数:
-a  :所有系统相关的信息,包括下面的数据都会被列出来;
-s  :系统核心名称
-r  :核心的版本
-m  :本系统的硬件名称,例如 i686 或 x86_64 等;
-p  :CPU 的类型,与 -m 类似,只是显示的是 CPU 的类型!
-i  :硬件的平台 (ix86)

范例一:输出系统的基本信息
[root@localhost ~]# uname -a
Linux localhost.localdomain 3.10.0-1160.el7.x86_64 #1 SMP Mon Oct 19 16:18:59 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux

3.4.3 uptime:查看系统启动时间与任务负载

显示出目前系统已经开机多久的时间,以及 1, 5, 15 分钟的平均负载,相当于显示top界面的最上面一行;

[root@localhost ~]# uptime
 09:54:40 up  6:08,  3 users,  load average: 0.00, 0.01, 0.05

3.4.4 netstat :追踪网络或socket P535

netstat常被用在网络的监控方面

[root@study ~]# netstat -[atunlp]
选项与参数:
-a  :将目前系统上所有的连接、监听、Socket 数据都列出来
-t  :列出 tcp 网络封包的信息
-u  :列出 udp 网络封包的信息
-n  :不以进程的服务名称,以端口号 (port number) 来显示;
-l  :列出目前正在网络监听 (listen) 的服务;
-p  :列出该网络服务的程序 PID

//范例一:列出目前系统已经创建的网络连线与 unix socket 状态
[root@localhost ~]# netstat
Active Internet connections (w/o servers)    #与网络较相关的地方
Proto Recv-Q Send-Q Local Address           Foreign Address         State
tcp        0     64 localhost.localdoma:ssh 192.168.64.1:54469      ESTABLISHED
Active UNIX domain sockets (w/o servers)    #与本机进程较相关的地方
Proto RefCnt Flags       Type       State         I-Node   Path
unix  3      [ ]         DGRAM                    9145     /run/systemd/notify
unix  2      [ ]         DGRAM                    9147     /run/systemd/cgroups-agent
unix  5      [ ]         DGRAM                    9168     /run/systemd/journal/socket
.....(下面省略).......

因特网络连线情况的部分:

  •  Proto :网络的封包协议,主要分为 TCP 与 UDP 封包,相关数据请参考服务器篇
  • Recv-Q:非由用户进程连接到此 socket 的复制的总 Bytes 数;
  • Send-Q:非由远程主机传送过来的 acknowledged 总 Bytes 数;
  • Local Address :本地端的 IP:port 情况
  • Foreign Address:远程主机的 IP:port 情况
  • State :连接状态,主要有建立(ESTABLISED)及监听(LISTEN);

socket file 可以沟通两个程序之间的信息,因此程序可以取得对方传送过来的数据

socket file 的输出字段有:

  • Proto :一般就是 unix ;
  • RefCnt:连接到此 socket 的进程数量;
  • Flags :连线的标识;
  • Type :socket 存取的类型。主要有确认连线的 STREAM 与不需确认的 DGRAM 两种;
  • State :若为 CONNECTED 表示多个进程之间已经建立连接。
  • Path :连接到此 socket 的相关进程的路径!或者是相关数据输出的路径
//范例二:找出目前系统上已在监听的网络连线及其 PID
[root@localhost ~]# 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:111             0.0.0.0:*               LISTEN      586/rpcbind
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      1128/sshd
tcp        0      0 127.0.0.1:631           0.0.0.0:*               LISTEN      1126/cupsd
tcp        0      0 127.0.0.1:25            0.0.0.0:*               LISTEN      1425/master
tcp6       0      0 :::111                  :::*                    LISTEN      586/rpcbind
tcp6       0      0 :::22                   :::*                    LISTEN      1128/sshd
tcp6       0      0 ::1:631                 :::*                    LISTEN      1126/cupsd
tcp6       0      0 ::1:25                  :::*                    LISTEN      1425/master
udp        0      0 0.0.0.0:5353            0.0.0.0:*                           578/avahi-daemon: r
udp        0      0 0.0.0.0:753             0.0.0.0:*                           586/rpcbind
udp        0      0 0.0.0.0:51113           0.0.0.0:*                           578/avahi-daemon: r
udp        0      0 0.0.0.0:67              0.0.0.0:*                           1313/dnsmasq
udp        0      0 0.0.0.0:68              0.0.0.0:*                           7145/dhclient
udp        0      0 0.0.0.0:111             0.0.0.0:*                           586/rpcbind
udp6       0      0 :::753                  :::*                                586/rpcbind
udp6       0      0 :::111                  :::*                                586/rpcbind

# 除了可以列出监听网络的接口与状态之外,最后一个字段还能够显示此服务的
# PID 号码以及程序的指令名称喔!例如上头的 1128 就是该 PID

//范例三:将上述的 0.0.0.0:51113 那个网络服务关闭的话?
[root@localhost ~]# kill -9 578
[root@localhost ~]# killall -9 avahi-daemon

3.4.5 dmesg :分析内核产生的信息

因为信息实在太多了,所以执行时可以加入这个管道命令【| more】来使界面暂停

//范例一:输出所有的核心开机时的信息
[root@localhost ~]# dmesg | more
//范例二:搜寻开机的时候,硬盘的相关信息为何?
[root@localhost ~]# dmesg | grep -i sda
[    2.067052] sd 0:0:0:0: [sda] 41943040 512-byte logical blocks: (21.4 GB/20.0 GiB)
[    2.067080] sd 0:0:0:0: [sda] Write Protect is off
[    2.067082] sd 0:0:0:0: [sda] Mode Sense: 61 00 00 00
[    2.067124] sd 0:0:0:0: [sda] Cache data unavailable
[    2.067125] sd 0:0:0:0: [sda] Assuming drive cache: write through
[    2.068351]  sda: sda1 sda2 sda3
.......省略......

3.4.6 vmstat :检测系统资源变化 P536

想要了解一个繁忙的系统到底是哪个环节最累人, 可以使用 vmstat 进行分析

[root@study ~]# vmstat [-a] [延迟 [总计检查次数]]  <==CPU/内存等信息
[root@study ~]# vmstat [-fs]                      <==内存相关
[root@study ~]# vmstat [-S 单位]                  <==设置显示数据的单位
[root@study ~]# vmstat [-d]                       <==与磁盘有关
[root@study ~]# vmstat [-p 分区]                  <==与磁盘有关
选项与参数:
-a  :使用 inactive/active(活跃与否) 取代 buffer/cache 的内存输出信息;
-f  :开机到目前为止,系统复制 (fork) 的程序数;
-s  :将一些事件 (启动至目前为止) 导致的内存变化情况列表说明;
-S  :后面可以接单位,让显示的数据有单位。例如 K/M 取代 Bytes 的容量;
-d  :列出磁盘的读写总量统计表
-p  :后面列出分区,可显示该分区的读写总量统计表

 //范例一:统计目前主机 CPU 状态,每秒一次,共计三次
[root@localhost ~]# 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
 2  0  26740  79636      0 180356    0    1    69     3   65  123  0  0 100  0  0
 0  0  26740  79636      0 180388    0    0     0     0   64  117  0  0 100  0  0
 0  0  26740  79636      0 180388    0    0     0     0   66  118  0  0 100  0  0

4 特殊文件与进程

 4.1 具有 SUID/SGID 权限的命令执行状态

SUID 的程序具有的特点:

  • SUID 权限仅对二进制程序(binary program)有效;
  • 执行者对于该程序需要具有 x 的可执行权限;
  • 本权限仅在执行该程序的过程中有效 (run-time);
  • 执行者将具有该程序拥有者 (owner) 的权限。
[dmtsai@study ~]$ passwd
Changing password for user dmtsai.
Changing password for dmtsai
(current) UNIX password: <==这里按下 [ctrl]-z 并且按下 [enter]
[1]+  Stopped                 passwd

[dmtsai@study ~]$ pstree -uA
systemd-+-ModemManager---2*[{ModemManager}]
....(中间省略)....
        |-sshd---sshd---sshd(dmtsai)---bash-+-passwd(root)
        |                                   `-pstree
....(下面省略)....
#查询整个系统中的SUID/SGID文件:
[root@localhost ~]# find / -perm /6000

4.2 /proc/* 代表的意义

内存中数据一般写入到/proc/*这个目录下:

[root@localhost ~]# ll /proc
总用量 0
dr-xr-xr-x. 216 root           root                         0 7月   4 16:50 .
dr-xr-xr-x.  18 root           root                       237 6月  28 15:53 ..
dr-xr-xr-x.   9 root           root                         0 7月   4 16:50 1
dr-xr-xr-x.   9 root           root                         0 7月   6 08:50 10
dr-xr-xr-x.   9 root           root                         0 7月   6 08:50 10783
.....(中间省略).......
-r--------.   1 root           root                         0 7月   6 08:55 vmallocinfo
-r--r--r--.   1 root           root                         0 7月   6 08:55 vmstat
-r--r--r--.   1 root           root                         0 7月   6 08:55 zoneinfo

主机上面的各个程序的 PID 都是以目录的形式存在于 /proc 当中。如开机所执行的第一支程序 systemd 的 PID 是 1 , 这个 PID 的所有相关信息都写入在 /proc/1/* 当中;

4.3 查询已使用文件或已执行进程使用的文件

4.3.1 fuser:借由文件(或文件系统)找出正在使用该文件的程序

[root@study ~]# fuser [-umv] [-k [i] [-signal]] file/dir
选项与参数:
-u  :除了进程的 PID 之外,同时列出该程序的拥有者;
-m  :后面接的那个文件名会主动的上提到该文件系统的最顶层,对 umount 不成功很有效!
-v  :可以列出每个文件与进程还有命令的完整相关性!
-k  :找出使用该文件/目录的 PID ,并试图以 SIGKILL 这个信号给予该 PID;
-i  :必须与 -k 配合,在删除 PID 之前会先询问使用者意愿!
-signal:例如 -1 -15 等等,若不加的话,默认是 SIGKILL (-9) 啰!

范例一:找出目前所在目录的使用 PID/所属帐号/权限为何?
[root@localhost ~]# fuser -uv .
                     用户     进程号 权限   命令
/root:               root       7286 ..c.. (root)bash
                     root      11500 ..c.. (root)bash

ACCESS 的项目代表的意义为:

  • c :此程序在当前的目录下(非次目录);
  • e :可被触发为执行状态;
  • f :是一个被打开的文件;
  • r :代表顶层目录 (root directory);
  • F :该文件被打开了,不过在等待回应中;
  • m :可能为分享的动态函数库;
范例二:找到所有使用到 /proc 这个文件系统的程序吧!
[root@localhost ~]# fuser -uv /proc
                     用户     进程号 权限   命令
/proc:               root     kernel mount (root)/proc
                     rtkit       582 .rc.. (rtkit)rtkit-daemon
# 数据量还不会很多,虽然这个目录很繁忙~没关系!我们可以继续这样作,看看其他的程序!
[root@localhost ~]# fuser -mvu /proc
                     用户     进程号 权限   命令
/proc:               root     kernel mount (root)/proc
                     root          1 f.... (root)systemd
                     root        374 f.... (root)systemd-journal
                    ......(中间省略).......
                     mcb        2095 f.... (mcb)gvfs-udisks2-vo
                     mcb        2227 f.... (mcb)gsd-housekeepin
                     mcb        2305 f.... (mcb)gvfsd-trash
# 有这几支程序在进行 /proc 文件系统的存取喔!这样清楚了吗?

范例三:找到所有使用到 /home 这个文件系统的程序吧!
[root@localhost ~]# echo $$
11500        # 先确认一下,自己的 bash PID 号码
[root@localhost ~]# cd /home
[root@localhost home]# fuser -muv .
                     用户     进程号 权限   命令
/home:               root     kernel mount (root)/
                     root          1 .rce. (root)systemd
                     ......(中间省略).......
                     root      11500 .rce. (root)bash    # 自己的 PID
[root@localhost ~]# umount /home
umount: /home: target is busy.
        (In some cases useful info about processes that use
         the device is found by lsof(8) or fuser(1))
# 从 fuser 的结果可以知道,总共有五只 process 在该目录下运行,那即使 root 离开了 /home,
# 当然还是无法 umount 的!那要怎办?哈哈!可以通过如下方法一个一个删除~
[root@localhost ~]# fuser -mki /home
/home:               31535c 31571c 31737c  # 你会发现, PID 跟上面查到的相同!
Kill process 31535 ? (y/N) # 这里会问你要不要删除!当然不要乱删除,通通取消!

4.3.2 lsof :列出被程序所打开的文件文件名 P542

与fuser相反,lsof是查出某个进程开启或使用的文件与设备;

[root@localhost ~]# lsof [-aUu] [+d]
选项与参数:
-a  :多项数据需要“同时成立”才显示出结果时!
-U  :仅列出 Unix like 系统的 socket 文件类型;
-u  :后面接 username,列出该使用者相关程序所打开的文件;
+d  :后面接目录,亦即找出某个目录下面已经被打开的文件!

范例一:列出目前系统上面所有已经被打开的文件与设备:
[root@localhost ~]# lsof
COMMAND   PID   TID    USER   FD   TYPE    DEVICE  SIZE/OFF       NODE NAME
systemd     1          root  cwd    DIR     253,0      4096        128 /
systemd     1          root  rtd    DIR     253,0      4096        128 /
systemd     1          root  txt    REG     253,0   1230920     967763 /usr/lib/systemd/systemd
....(下面省略)....
# 在默认的情况下, lsof 会将目前系统上面已经打开的
# 文件全部列出来;所以,可以注意到,第一个文件 systemd 执行的
# 地方就在根目录,而根目录所在的 inode 也有显示出来!

4.3.3 pidof :找出某个正在执行的进程的 PID

[root@study ~]# pidof [-sx] program_name
选项与参数:
-s  :仅列出一个 PID 而不列出所有的 PID
-x  :同时列出该 program name 可能的 PPID 那个程序的 PID

范例一:列出目前系统上面 systemd 以及 rsyslogd 这两个程序的 PID
[root@localhost ~]# pidof systemd rsyslogd
1 1130

5 SELinux (P543)

SELinux安全强化的linux之意;

自主访问控制与强制访问控制的区别:

 左图是没有 SELinux 的 DAC 存取结果,apache 这个 root 所主导的程序,可以在这三个目录内作任何文件的新建与修改;右边则是加上 SELinux 的 MAC 管理的结果,SELinux 仅会针对 Apache 这个【进程】开放部分的目录, 其他的非正规目录就不会让Apache 使用!因此不管你是谁,就是不能穿透 MAC 的框框;

SELinux 重点在保护进程读取文件系统的权限

主体与目标的安全上下文必须一致才能够顺利读写;

# 再来观察一下系统“程序的 SELinux 相关信息”
[root@localhost ~]# ps -eZ
LABEL                              PID TTY          TIME CMD
system_u:system_r:init_t:s0          1 ?        00:00:04 systemd
system_u:system_r:kernel_t:s0        2 ?        00:00:00 kthreadd
system_u:system_r:kernel_t:s0        4 ?        00:00:00 kworker/0:0H
......(中间省略)......
system_u:system_r:local_login_t:s0-s0:c0.c1023 2855 ? 00:00:00 login
unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 7214 tty2 00:00:00 bash
# 基本上程序主要就分为两大类,一种是系统有受限的 system_u:system_r,另一种则可能是用户自己的,
# 比较不受限的程序 (通常是本机用户自己执行的程序),亦即是 unconfined_u:unconfined_r 这两种!

5.1 SELinux 三种模式的启动、关闭与查看

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值