该系列目录 --> 【BASH】回顾与知识点梳理(目录)
进程之间是可以互相控制的!举例来说,你可以关闭、重新启动服务器软件,服务器软件本身是个进程, 你既然可以让她关闭或启动,当然就是可以控制该进程啦!那么进程是如何互相管理的呢?其实是透过给予该进程一个讯号 (signal) 去告知该进程你想要让她作什么
!因此这个讯号就很重要啦!
要给予某个已经存在背景中的工作某些动作时,是直接给予一个讯号给该工作号码即可。那么到底有多少 signal 呢? 你可以使用kill -l
(小写的 L ) 或者是 man 7 signal 都可以查询到!主要的讯号代号与名称对应及内容是:
代号 | 名称 | 内容 |
---|---|---|
1 | SIGHUP | 启动被终止的进程,可让该 PID 重新读取自己的配置文件,类似重新启动 |
2 | SIGINT | 相当于用键盘输入 [ctrl]-c 来中断一个进程的进行 |
9 | SIGKILL | 代表强制中断一个进程的进行,如果该进程进行到一半, 那么尚未完成的部分可能会有『半产品』产生, 类似 vim 会有 .filename.swp 保留下来。 |
15 | SIGTERM | 以正常的结束进程来终止该进程。由于是正常的终止, 所以后续的动作会将他完成。 不过,如果该进程已经发生问题,就是无法使用正常的方法终止时, 输入这个 signal 也是没有用的。 |
19 | SIGSTOP | 相当于用键盘输入 [ctrl]-z 来暂停一个进程的进行 |
上面仅是常见的 signal 而已,更多的讯号信息请自行 man 7 signal 吧!一般来说,你只要记得『1, 9, 15
』这三个号码的意义即可。那么我们如何传送一个讯号给某个进程呢?就透过 kill 或 killall 吧!底下分别来看看:
kill 可以帮我们将这个 signal 传送给某个工作 (%jobnumber
) 或者是某个 PID
(直接输入数字)。 要再次强调的是: kill 后面直接加数字与加上 %number 的情况是不同的
! 这个很重要喔!因为工作控制中有 1 号工作,但是 PID 1 号则是专指『 systemd 』这支程序!你怎么可以将 systemd 关闭呢? 关闭 systemd ,你的系统就当掉了啊!所以记得那个 % 是专门用在工作控制的
喔! 我们就活用一下 kill 与刚刚上面提到的 ps 来做个简单的练习吧!
例题:以 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
了解了这个用法以后,如果未来你想要将某个莫名其妙的登入者的联机删除的话,就可以透过使用pstree -p
找到相关进程, 然后再以kill -9
将该进程删除,该条联机就会被踢掉了!这样很简单吧!
进程名 | 说明 |
---|---|
systemd | 是 Linux 中最新的启动进程系统,它被设计为用于管理和监控整个系统的进程。systemd 可以启动其他进程,跟踪它们的 PID,当需要停止进程时,用 systemd 可以很容易地终止进程。在命令行中,我们可以使用以下命令来启动和停止 systemd 进程: systemctl start systemdsystemctl stop systemd |
crond | crond 是一个用于定时任务的进程,它可以在指定的时间运行命令或脚本。通过 crontab 命令,用户可以创建或修改定时任务,crond 每分钟扫描一次任务列表,执行满足条件的任务。 systemctl start crondsystemctl stop crond |
sshd | sshd 是一个用于远程登录的安全 shell 服务进程,它使用户可以从远程系统登录并管理本地系统。作为一种安全的远程登录方式,sshd 提供了密钥交换和加密通信等功能,确保用户的登录数据和命令不被窃取和篡改。 systemctl start sshdsystemctl stop sshd |
network | network 进程是一个核心网络配置的进程,它包含了 Linux 网络设置中的所有业务代码,包括网络命令,网络状态监测,网络配置的重启等等。当我们需要配置网络,修改 IP 地址,打开 or 关闭子网时,我们通常使用以下命令来启动和停止 network 进程: systemctl start networksystemctl stop network |
rsyslogd | rsyslogd 又称系统日志服务,它是一个日志转发的进程,可以将 Linux 系统的日志信息发送到本地或远程服务器中,使我们能够在一个地方查看所有系统日志信息。 systemctl start rsyslogdsystemctl stop rsyslogd |
dbus-daemon | dbus-daemon 是一个进程总线的守护进程,它是一个 Linux 系统中的消息路由器,允许不同的进程通过它而相互通信。通过 dbus-daemon,系统进程之间可以相互发送信息,进行通信,从而实现相互协作。 systemctl start dbus-daemonsystemctl stop dbus-daemon |
udevd | udev 是 Linux 中的设备管理机制,可以自动检测和管理系统中的硬件设备。通过 udev,当新的硬件设备连接到系统时,系统会自动识别该设备并创建相应的设备节点等信息,从而让 Linux 系统更好地识别,管理和使用硬件设备。 systemctl start udevdsystemctl stop udevd |
kerneloops | kerneloops 是一个收集 Linux 内核崩溃信息和提供给用户的简单工具,它可以检测 Linux 内核的错误,收集相关信息,并将错误信息发送到相关服务器,然后对异常做统计分析,从而让用户更好地了解系统崩溃的情况。 systemctl start kerneloopssystemctl stop kerneloops |
tuned | tuned 是一个可以优化 Linux 系统性能的工具,它可以根据系统负载和特定配置策略来调整系统的资源分配和管理,从而提高系统运行效率和稳定性。 systemctl start tunedsystemctl stop tuned |
nscd | nscd 是一个进程缓存的守护进程,并通过本地缓存重新获取常用的系统数据,以避免不必要的系统资源浪费和网络带宽占用。nscd 可以缓存每个用户和组的信息,提高系统处理速度。 systemctl start nscdsystemctl stop nscd |
VGAuthService | VMware Guest Authentication Service 相关进程 |
NetworkManager | 和network相似,都是网络管理工具,一般有一个即可 |
dhclient | (DHCP client)为动态主机配置协议客户端。DHCP 客户端 dhclient 提供了一种使用动态主机配置协议 和 BOOTP 协议配置一个或多个网络接口的方法。如果这些协议失败,则通过静态分配地址来配置。 |
由于 kill 后面必须要加上 PID (或者是 job number),所以,通常 kill 都会配合 ps, pstree 等指令,因为我们必须要找到相对应的那个进程的 ID 嘛!但是,如此一来,很麻烦~有没有可以利用『下达指令的名称』来给予讯号的?举例来说,能不能直接将 rsyslogd 这个进程给予一个 SIGHUP 的讯号呢?可以的!用 killall 吧!
[root@study ~]# killall [-iIe] [command name]
选项与参数:
-i :interactive 的意思,交互式的,若需要删除时,会出现提示字符给用户;
-e :exact 的意思,表示『后面接的 command name 要一致』,但整个完整的指令不能超过 15 个字符。
-I :指令名称(可能含参数)忽略大小写。
# 范例一:给予 rsyslogd 这个指令启动的 PID 一个 SIGHUP 的讯号
[root@study ~]# killall -1 rsyslogd
# 如果用 ps aux 仔细看一下,若包含所有参数,则 /usr/sbin/rsyslogd -n 才是最完整的!
# 范例二:强制终止所有以 httpd 启动的进程 (其实并没有此进程在系统内)
[root@study ~]# killall -9 httpd
# 范例三:依次询问每个 bash 程序是否需要被终止运作!
[root@study ~]# killall -i -9 bash
Signal bash(13888) ? (y/N) n <==这个不杀!
Signal bash(13928) ? (y/N) n <==这个不杀!
Signal bash(13970) ? (y/N) n <==这个不杀!
Signal bash(14836) ? (y/N) y <==这个杀掉!
# 具有互动的功能!可以询问你是否要删除 bash 这个程序。要注意,若没有 -i 的参数,
# 所有的 bash 都会被这个 root 给杀掉!包括 root 自己的 bash 喔! ^_^
总之,要删除某个进程,我们可以使用 PID 或者是启动该进程的指令名称, 而如果要删除某个服务呢?呵呵!最简单的方法就是利用 killall , 因为他可以将系统当中所有以某个指令名称启动的进程全部删除。 举例来说,上面的范例二当中,系统内所有以 httpd 启动的进程,就会通通的被删除啦! ^_^
我们知道 Linux 是多人多任务的环境,由 top 的输出结果我们也发现, 系统同时间有非常多的进程在运行中,只是绝大部分的进程都在休眠 (sleeping) 状态而已。 想一想,如果所有的进程同时被唤醒,那么 CPU 应该要先处理那个进程呢?也就是说,那个进程被执行的优先序比较高? 这就得要考虑到进程的优先执行顺序 (Priority)
与 CPU 排程
啰!
CPU 排程与前一章的例行性工作排程并不一样。 CPU 排程指的是每支进程被 CPU 运作的演算规则, 而例行性工作排程则是将某支程序安排在某个时间再交由系统执行。 CPU 排程与操作系统较具有相关性!
我们知道 CPU 一秒钟可以运作多达数 G 的微指令次数,透过核心的 CPU 排程可以让各进程被CPU 所切换运作, 因此每个进程在一秒钟内或多或少都会被 CPU 执行部分的脚本
。如果进程都是集中在一个队列中等待 CPU 的运作, 而不具有优先级之分,也就是像我们去游乐场玩热门游戏需要排队一样,每个人都是照顺序来! 你玩过一遍后还想再玩 (没有执行完毕),请到后面继续排队等待。情况有点像底下这样:
上图中假设 pro1, pro2 是紧急的进程, pro3, pro4 是一般的进程,在这样的环境中,由于不具有优先级, 唉啊!pro1, pro2 还是得要继续等待而没有优待呢!如果 pro3, pro4 的工作又臭又长!那么紧急的 pro1, pro2 就得要等待个老半天才能够完成!真麻烦啊!所以啰,我们想要将进程分优先级啦!如果优先序较高则运作次数可以较多次, 而不需要与较慢优先的进程抢位置!我们可以将进程的优先级与 CPU 排程进行如下图的解释:
如上图所示,具高优先权的 pro1, pro2 可以被取用两次,而较不重要的 pro3, pro4 则运作次数较少。如此一来 pro1, pro2 就可以较快被完成啦!要注意,上图仅是示意图,并非较优先者一定会被运作两次啦! 为了要达到上述的功能,我们 Linux 给予进程一个所谓的『优先执行序 (priority, PRI)
』,这个 PRI 值越低代表越优先的意思。不过这个 PRI 值是由核心动态调整的,用户无法直接调整 PRI 值的。先来瞧瞧 PRI 曾在哪里出现?
[root@study ~]# ps -l
F S UID PID PPID C PRI NI ADDR SZ WCHAN TTY TIME CMD
4 S 0 14836 14835 0 90 10 - 29068 wait pts/0 00:00:00 bash
0 R 0 19848 14836 0 90 10 - 30319 - pts/0 00:00:00 ps
# 你应该要好奇,怎么我的 NI 已经是 10 了?还记得刚刚 top 的测试吗?我们在那边就有改过一次喔!
由于 PRI 是核心动态调整的,我们用户也无权去干涉 PRI !那如果你想要调整进程的优先执行序时,就得要透过 Nice 值了!Nice 值就是上表的 NI 啦!一般来说, PRI 与 NI 的相关性如下:
PRI(new) = PRI(old) + nice
不过你要特别留意到,如果原本的 PRI 是 50 ,并不是我们给予一个 nice = 5 ,就会让 PRI 变成 55 喔! 因为 PRI 是系统『动态』决定的,所以,虽然 nice 值是可以影响 PRI ,不过, 最终的 PRI 仍是要经过系统分析后才会决定的
。另外, nice 值是有正负的喔,而既然 PRI 越小越早被执行, 所以,当 nice 值为负值时,那么该进程就会降低 PRI 值,亦即会变的较优先被处理。此外,你必须要留意到:
这也就是说,要调整某个进程的优先执行序,就是『调整该进程的 nice 值
』啦!那么如何给予某个进程 nice 值呢?有两种方式,分别是:
[root@study ~]# nice [-n 数字] command
选项与参数:
-n :后面接一个数值,数值的范围 -20 ~ 19。
# 范例一:用 root 给一个 nice 值为 -5 ,用于执行 vim ,并观察该进程!
[root@study ~]# nice -n -5 vim &
[1] 19865
[root@study ~]# ps -l
F S UID PID PPID C PRI NI ADDR SZ WCHAN TTY TIME CMD
4 S 0 14836 14835 0 90 10 - 29068 wait pts/0 00:00:00 bash
4 T 0 19865 14836 0 85 5 - 37757 signal pts/0 00:00:00 vim
0 R 0 19866 14836 0 90 10 - 30319 - pts/0 00:00:00 ps
# 原本的 bash PRI 为 90 ,所以 vim 预设应为 90。不过由于给予 nice 为 -5 ,
# 因此 vim 的 PRI 降低了!RPI 与 NI 各减 5 !但不一定每次都是正好相同喔!因为核心会动态调整
[root@study ~]# kill -9 %1 <==测试完毕将 vim 关闭
就如同前面说的, nice 是用来调整进程的执行优先级!这里只是一个执行的范例罢了! 通常什么时候要将 nice 值调大呢?举例来说,系统的背景工作中, 某些比较不重要的进程之进行:例如备份工作!由于备份工作相当的耗系统资源, 这个时候就可以将备份的指令之 nice 值调大一些,可以使系统的资源分配的更为公平!
[root@study ~]# renice [number] PID
选项与参数:
PID :某个进程的 ID 啊!
# 范例一:找出自己的 bash PID ,并将该 PID 的 nice 调整到 -5
[root@study ~]# ps -l
F S UID PID PPID C PRI NI ADDR SZ WCHAN TTY TIME CMD
4 S 0 14836 14835 0 90 10 - 29068 wait pts/0 00:00:00 bash
0 R 0 19900 14836 0 90 10 - 30319 - pts/0 00:00:00 ps
[root@study ~]# renice -5 14836
14836 (process ID) old priority 10, new priority -5
[root@study ~]# ps -l
F S UID PID PPID C PRI NI ADDR SZ WCHAN TTY TIME CMD
4 S 0 14836 14835 0 75 -5 - 29068 wait pts/0 00:00:00 bash
0 R 0 19910 14836 0 75 -5 - 30319 - pts/0 00:00:00 ps
由上面这个范例当中我们也看的出来,虽然修改的是 bash 那个进程,但是该进程所触发的 ps 指令当中的 nice 也会继承而为 -5 喔!了解了吧!整个 nice 值是可以在父进程 --> 子进程之间传递的呢! 另外,除了 renice 之外,其实那个 top 同样的也是可以调整 nice 值的
!
除了系统的进程之外,我们还必须就系统的一些资源进行检查啊!举例来说,我们使用 top 可以看到很多系统的资源对吧!那么,还有没有其他的工具可以查阅的? 当然有啊!底下这些工具指令可以玩一玩!
[root@study ~]# 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 n:可以让系统每几秒钟输出一次,不间断的一直输出的意思!对于系统观察挺有效!
-c n:与 -s 同时处理~让 free 列出几次的意思~
# 范例一:显示目前系统的内存容量
[root@study ~]# free -m
total used free shared buff/cache available
Mem: 2848 346 1794 8 706 2263
Swap: 1023 0 1023
Mem 那一行显示的是物理内存的量, Swap 则是内存置换空间的量。 total 是总量, used 是已被使用的量, free 则是剩余可用的量。 后面的shared/buffers/cached
则是在已被使用的量当中,用来作为缓冲及快取的量,这些 shared/buffers/cached 的用量中,在系统比较忙碌时,可以被释出而继续利用!因此后面就有一个 available (可用的) 数值!。
请看上头范例一的输出,我们可以发现这部测试机根本没有什么特别的服务,但是竟然有 706MB 左右的 cache 耶! 因为鸟哥在测试过程中还是有读/写/执行很多的文件嘛!这些文件就会被系统暂时快取下来,等待下次运作时可以更快速的取出之意! 也就是说,系统是『很有效率的将所有的内存用光光
』,目的是为了让系统的存取效能加速啦!
很多朋友都会问到这个问题『我的系统明明很轻松,为何内存会被用光光?』现在瞭了吧? 被用光是正常的!而需要注意的反而是 swap 的量。一般来说, swap 最好不要被使用,尤其 swap 最好不要被使用超过 20% 以上, 如果您发现 swap 的用量超过 20% ,那么,最好还是买物理内存来插吧! 因为, Swap 的效能跟物理内存实在差很多,而系统会使用到 swap , 绝对是因为物理内存不足了才会这样做的
!如此,了解吧!
Linux 系统为了要加速系统效能,所以会将最常使用到的或者是最近使用到的文件数据快取 (cache) 下来, 这样未来系统要使用该文件时,就直接由内存中搜寻取出,而不需要重新读取硬盘,速度上面当然就加快了! 因此,物理内存被用光是正常的喔!
[root@study ~]# uname [-asrmpi]
选项与参数:
-a :所有系统相关的信息,包括底下的数据都会被列出来;
-s :系统核心名称
-r :核心的版本
-m :本系统的硬件名称,例如 i686 或 x86_64 等;
-p :CPU 的类型,与 -m 类似,只是显示的是 CPU 的类型!
-i :硬件的平台 (ix86)
# 范例一:输出系统的基本信息
[root@node-135 ~]# uname -a
Linux node-135 3.10.0-1160.92.1.el7.x86_64 #1 SMP Tue Jun 20 11:48:01 UTC 2023 x86_64 x86_64 x86_64 GNU/Linux
[root@node-135 ~]# uname -s
Linux
[root@node-135 ~]# uname -r
3.10.0-1160.92.1.el7.x86_64
[root@node-135 ~]# uname -m
x86_64
[root@node-135 ~]# uname -p
x86_64
[root@node-135 ~]# uname -i
x86_64
这个咚咚我们前面使用过很多次了喔!uname 可以列出目前系统的核心版本、 主要硬件平台以及CPU 类型等等的信息。以上面范例一的状态来说,我的 Linux 主机使用的核心名称为 Linux,而主机名为 study.centos.vbird,核心的版本为 3.10.0-1160.92.1.el7.x86_64 ,该核心版本建立的日期为 2023-6-20,适用的硬件平台为 x86_64 以上等级的硬件平台喔。
这个指令很单纯呢!就是显示出目前系统已经开机多久的时间,以及 1, 5, 15 分钟的平均负载就是了。还记得 top 吧?没错啦!这个 uptime 可以显示出 top 画面的最上面一行!
[root@study ~]# uptime
02:35:27 up 7:48, 3 users, load average: 0.00, 0.01, 0.05
# top 这个指令已经谈过相关信息,不再聊!
这个 netstat 也是挺好玩的,其实这个指令比较常被用在网络的监控方面,不过,在进程管理方面也是需要了解的啦! 这个指令的执行如下所示:基本上, netstat 的输出分为两大部分,分别是网络与系统自己的进程相关性部分:
[root@study ~]# netstat -[atunlp]
选项与参数:
-a :将目前系统上所有的联机、监听、Socket 数据都列出来
-t :列出 tcp 网络封包的数据
-u :列出 udp 网络封包的数据
-n :不以进程的服务名称,以埠号 (port number) 来显示;
-l :列出目前正在网络监听 (listen) 的服务;
-p :列出该网络服务的进程 PID
# 范例一:列出目前系统已经建立的网络联机与 unix socket 状态
[root@study ~]# netstat
Active Internet connections (w/o servers) <==与网络较相关的部分
Proto Recv-Q Send-Q Local Address Foreign Address State
tcp 0 0 172.16.15.100:ssh 172.16.220.234:48300 ESTABLISHED
Active UNIX domain sockets (w/o servers) <==与本机的进程自己的相关性(非网络)
Proto RefCnt Flags Type State I-Node Path
unix 2 [ ] DGRAM 1902 @/org/freedesktop/systemd1/notify
unix 2 [ ] DGRAM 1944 /run/systemd/shutdownd
....(中间省略)....
unix 3 [ ] STREAM CONNECTED 25425 @/tmp/.X11-unix/X0
unix 3 [ ] STREAM CONNECTED 28893
unix 3 [ ] STREAM CONNECTED 21262
在上面的结果当中,显示了两个部分,分别是网络的联机以及 linux 上面的 socket 进程相关性部分。我们先来看看因特网联机情况的部分:
我们看上面仅有一条联机的数据,他的意义是:『透过 TCP 封包的联机,远程的 172.16.220.234:48300 联机到本地端的 172.16.15.100:ssh ,这条联机状态是建立 (ESTABLISHED) 的状态!』
本机进程通信
除了网络上的联机之外,其实 Linux 系统上面的进程是可以接收不同进程所发送来的信息,那就是Linux 上头的插槽档 (socket file)
。socket file 可以沟通两个进程之间的信息,因此进程可以取得对方传送过来的资料。 由于有 socket file,因此类似 X Window 这种需要透过网络连接的软件,目前新版的 distributions 就以 socket 来进行窗口接口的联机沟通了。上表中 socket file 的输出字段有:
以上表的输出为例,最后那三行在 /tmp/.xx 底下的数据,就是 X Window 窗口接口的相关进程啦!而 PATH 指向的就是这些进程要交换数据的插槽文件啰!好!那么 netstat 可以帮我们进行什么任务呢? 很多喔!我们先来看看,利用 netstat 去看看我们的哪些进程有启动哪些网络的『后门』呢?
# 范例二:找出目前系统上已在监听的网络联机及其 PID
[root@study ~]# 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:22 0.0.0.0:* LISTEN 1326/sshd
tcp 0 0 127.0.0.1:25 0.0.0.0:* LISTEN 2349/master
tcp6 0 0 :::22 :::* LISTEN 1326/sshd
tcp6 0 0 ::1:25 :::* LISTEN 2349/master
udp 0 0 0.0.0.0:123 0.0.0.0:* 751/chronyd
udp 0 0 127.0.0.1:323 0.0.0.0:* 751/chronyd
udp 0 0 0.0.0.0:57808 0.0.0.0:* 743/avahi-daemon: r
udp 0 0 0.0.0.0:5353 0.0.0.0:* 743/avahi-daemon: r
udp6 0 0 :::123 :::* 751/chronyd
udp6 0 0 ::1:323 :::* 751/chronyd
# 除了可以列出监听网络的接口与状态之外,最后一个字段还能够显示此服务的
# PID 号码以及进程的指令名称喔!例如上头的 1326 就是该 PID
# 范例三:将上述的 0.0.0.0:57808 那个网络服务关闭的话?
[root@study ~]# kill -9 743
[root@study ~]# killall -9 avahi-daemon
很多朋友常常有疑问,那就是,我的主机目前到底开了几个门(ports)!其实,不论主机提供什么样的服务, 一定必须要有相对应的 program 在主机上面执行才行啊!举例来说,我们鸟园的 Linux 主机提供的就是 WWW 服务,那么我的主机当然有一个程序在提供 WWW 的服务啊!那就是 Apache 这个软件所提供的啦!^_^。 所以,当我执行了这个程序之后,我的系统自然就可以提供 WWW 的服务了。那如何关闭啊? 就关掉该程序所触发的那个进程就好了!例如上面的范例三所提供的例子啊!不过,这个是非正规的作法喔! 正规的作法,请查阅下一章的说明呦!
系统在开机的时候,核心会去侦测系统的硬件,你的某些硬件到底有没有被捉到,那就与这个时候的侦测有关。 但是这些侦测的过程要不是没有显示在屏幕上,就是很飞快的在屏幕上一闪而逝!能不能把核心侦测的讯息捉出来瞧瞧? 可以的,那就使用 dmesg 吧!
所有核心侦测的讯息,不管是开机时候还是系统运作过程中,反正只要是核心产生的讯息,都会被记录到内存中的某个保护区段。 dmesg 这个指令就能够将该区段的讯息读出来的!因为讯息实在太多了,所以执行时可以加入这个管线指令『 | more
』来使画面暂停!
# 范例一:输出所有的核心开机时的信息
[root@study ~]# dmesg | more
# 范例二:搜寻开机的时候,硬盘的相关信息为何?
[root@study ~]# dmesg | grep -i vda
[ 0.758551] vda: vda1 vda2 vda3 vda4 vda5 vda6 vda7 vda8 vda9
[ 3.964134] XFS (vda2): Mounting V4 Filesystem
....(底下省略)....
由范例二就知道我这部主机的硬盘的格式是什么了吧!
如果你想要动态的了解一下系统资源的运作,那么这个 vmstat 确实可以玩一玩!vmstat 可以侦测『 CPU / 内存 / 磁盘输入输出状态
』等等,如果你想要了解一部繁忙的系统到底是哪个环节最累人, 可以使用 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@study ~]# 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
1 0 0 1838092 1504 722216 0 0 4 1 6 9 0 0 100 0 0
0 0 0 1838092 1504 722200 0 0 0 0 13 23 0 0 100 0 0
0 0 0 1838092 1504 722200 0 0 0 0 25 46 0 0 100 0 0
利用 vmstat 甚至可以进行追踪喔!你可以使用类似『 vmstat 5
』代表每五秒钟更新一次,且无穷的更新!直到你按下 [ctrl]-c 为止。如果你想要实时的知道系统资源的运作状态,这个指令就不能不知道!那么上面的表格各项字段的意义为何? 基本说明如下:
r :等待运作中的进程数量;
b:不可被唤醒的进程数量。
这两个项目越多,代表系统越忙碌 (因为系统太忙,所以很多进程就无法被执行或一直在等待而无法被唤醒之故)。
swpd:虚拟内存被使用的容量;
free:未被使用的内存容量;
buff:用于缓冲存储器;
cache:用于高速缓存。
这部份则与 free 是相同的。
si:由磁盘中将进程取出的量;
so:由于内存不足而将没用到的进程写入到磁盘的 swap 的容量。
如果 si/so 的数值太大,表示内存内的数据常常得在磁盘与主存储器之间传来传去,系统效能会很差!
bi:由磁盘读入的区块数量;
bo:写入到磁盘去的区块数量。
如果这部份的值越高,代表系统的 I/O 非常忙碌!
in:每秒被中断的进程次数;
cs:每秒钟进行的事件切换次数;
这两个数值越大,代表系统与接口设备的沟通非常频繁! 这些接口设备当然包括磁盘、网络卡、时间钟等。
由于鸟哥的机器是测试机,所以并没有什么 I/O 或者是 CPU 忙碌的情况。如果改天你的服务器非常忙碌时,记得使用 vmstat 去看看,到底是哪个部分的资源被使用的最为频繁!一般来说,如果 I/O 部分很忙碌的话,你的系统会变的非常慢! 让我们再来看看,那么磁盘的部分该如何观察:
# 范例二:系统上面所有的磁盘的读写状态
[root@study ~]# vmstat -d
disk- ------------reads------------ ------------writes----------- -----IO------
total merged sectors ms total merged sectors ms cur sec
vda 21928 0 992587 47490 7239 2225 258449 13331 0 26
sda 395 1 3168 213 0 0 0 0 0 0
sr0 0 0 0 0 0 0 0 0 0 0
dm-0 19139 0 949575 44608 7672 0 202251 16264 0 25
dm-1 336 0 2688 327 0 0 0 0 0 0
md0 212 0 1221 0 14 0 4306 0 0 0
dm-2 218 0 9922 565 54 0 4672 128 0 0
dm-3 179 0 957 182 11 0 4306 68 0 0
我们在前面曾经谈到特殊权限的 SUID/SGID/SBIT
,虽然已经将这三种特殊权限作了详细的解释,不过,我们依旧要来探讨的是,那么到底这些权限对于你的『进程』是如何影响的?
此外,进程可能会使用到系统资源,举例来说,磁盘就是其中一项资源。哪天你在 umount 磁盘时,系统老是出现『 device is busy 』的字样~到底是怎么回事啊?我们底下就来谈一谈这些和进程有关系的细节部分:
SUID 的权限其实与进程的相关性非常的大
!为什么呢?先来看看 SUID 的程序是如何被一般用户执行,且具有什么特色呢?
所以说,整个 SUID 的权限会生效是由于『具有该权限的程序被触发』,而我们知道一个程序被触发会变成进程, 所以啰,执行者可以具有程序拥有者的权限就是在该程序变成进程的那个时候啦!或许那时候会觉得很奇怪,为啥执行了 passwd 后你就具有 root 的权限呢?不都是一般使用者执行的吗? 这是因为你在触发 passwd 后,会取得一个新的进程与 PID,该 PID 产生时透过 SUID 来给予该 PID 特殊的权限设定啦! 我们使用 dmtsai 登入系统且执行 passwd 后,透过工作控制来理解一下!
[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
....(底下省略)....
从上表的结果我们可以发现,底线的部分(sshd(dmtsai)---bash,
-pstree)是属于 dmtsai 这个一般账号的权限,特殊字体(passwd(root))的则是 root 的权限! 但你看到了, passwd 确实是由 bash 衍生出来的!不过就是权限不一样
!透过这样的解
析, 你也会比较清楚为何不同程序所产生的权限不同了吧!这是由于『SUID 程序运作过程中产生的进程』的关系啦!
那么既然 SUID/SGID 的权限是比较可怕的,您该如何查询整个系统的 SUID/SGID 的文件呢? 应该是还不会忘记吧?使用 find 即可啊!
find / -perm /6000
其实,我们之前提到的所谓的进程都是在内存当中嘛!而内存当中的数据又都是写入到 /proc/*
这个目录下的,所以啰,我们当然可以直接观察 /proc 这个目录当中的文件啊! 如果你观察过 /proc 这个目录的话,应该会发现他有点像这样:
[root@study ~]# ll /proc
dr-xr-xr-x. 8 root root 0 Aug 4 18:46 1
dr-xr-xr-x. 8 root root 0 Aug 4 18:46 10
dr-xr-xr-x. 8 root root 0 Aug 4 18:47 10548
....(中间省略)....
-r--r--r--. 1 root root 0 Aug 5 17:48 uptime
-r--r--r--. 1 root root 0 Aug 5 17:48 version
-r--------. 1 root root 0 Aug 5 17:48 vmallocinfo
-r--r--r--. 1 root root 0 Aug 5 17:48 vmstat
-r--r--r--. 1 root root 0 Aug 5 17:48 zoneinfo
基本上,目前主机上面的各个进程的 PID 都是以目录的型态存在于 /proc 当中。 举例来说,我们开机所执行的第一支程序 systemd 他的 PID 是 1 , 这个 PID 的所有相关信息都写入在 /proc/1/*
当中!若我们直接观察 PID 为 1 的数据好了,他有点像这样:
[root@study ~]# ll /proc/1
dr-xr-xr-x. 2 root root 0 Aug 4 19:25 attr
-rw-r--r--. 1 root root 0 Aug 4 19:25 autogroup
-r--------. 1 root root 0 Aug 4 19:25 auxv
-r--r--r--. 1 root root 0 Aug 4 18:46 cgroup
--w-------. 1 root root 0 Aug 4 19:25 clear_refs
-r--r--r--. 1 root root 0 Aug 4 18:46 cmdline <==就是指令串
-r--------. 1 root root 0 Aug 4 18:46 environ <==一些环境变量
lrwxrwxrwx. 1 root root 0 Aug 4 18:46 exe
....(以下省略)....
里面的数据还挺多的,不过,比较有趣的其实是两个文件,分别是:
[root@study ~]# cat /proc/1/cmdline
/usr/lib/systemd/systemd--switched-root--system--deserialize24
就是这个指令、选项与参数启动 systemd 的啦!这还是跟某个特定的 PID 有关的内容呢,如果是针对整个 Linux 系统相关的参数呢?那就是在 /proc 目录底下的文件啦!相关的文件与对应的内容是这样的:
檔名 | 文件内容 |
---|---|
/proc/cmdline | 加载 kernel 时所下达的相关指令与参数!查阅此文件,可了解指令是如何启动的! |
/proc/cpuinfo | 本机的 CPU 的相关信息,包含频率、类型与运算功能等 |
/proc/devices | 这个文件记录了系统各个主要装置的主要装置代号,与 mknod 有关呢! |
/proc/filesystems | 目前系统已经加载的文件系统啰! |
/proc/interrupts | 目前系统上面的 IRQ 分配状态。 |
/proc/ioports | 目前系统上面各个装置所配置的 I/O 地址。 |
/proc/kcore | 这个就是内存的大小啦!好大对吧!但是不要读他啦! |
/proc/loadavg | 还记得 top 以及 uptime 吧?没错!上头的三个平均数值就是记录在此! |
/proc/meminfo | 使用 free 列出的内存信息,嘿嘿!在这里也能够查阅到! |
/proc/modules | 目前我们的 Linux 已经加载的模块列表,也可以想成是驱动程序啦! |
/proc/mounts | 系统已经挂载的数据,就是用 mount 这个指令呼叫出来的数据啦! |
/proc/swaps | 到底系统挂加载的内存在哪里?呵呵!使用掉的 partition 就记录在此啦! |
/proc/partitions | 使用 fdisk -l 会出现目前所有的 partition 吧?在这个文件当中也有纪录喔! |
/proc/uptime | 就是用 uptime 的时候,会出现的信息啦! |
/proc/version | 核心的版本,就是用 uname -a 显示的内容啦! |
/proc/bus/* | 一些总线的装置,还有 USB 的装置也记录在此喔! |
其实,上面这些文件鸟哥在此建议您可以使用 cat 去查阅看看,不必深入了解, 不过,观看过文件内容后,毕竟会比较有感觉啦!如果未来您想要自行撰写某些工具软件, 那么这个目录底下的相关文件可能会对您有点帮助的喔!
其实还有一些与进程相关的指令可以值得参考与应用的,我们来谈一谈:
有的时候我想要知道我的进程到底在这次启动过程中开启了多少文件,可以利用 fuser 来观察啦!举例来说,你如果卸除时发现系统通知:『 device is busy 』,那表示这个文件系统正在忙碌中, 表示有某支进程有利用到该文件系统啦!那么你就可以利用 fuser 来追踪啰!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@study ~]# fuser -uv .
USER PID ACCESS COMMAND
/root: root 13888 ..c.. (root)bash
root 31743 ..c.. (root)bash
看到输出的结果没?他说『.
』底下有两个 PID 分别为 13888, 31743 的进程,该进程属于 root 且指令为 bash 。 比较有趣的是那个 ACCESS 的项目,那个项目代表的意义为:
那如果你想要查阅某个文件系统底下有多少进程正在占用该文件系统时,那个 -m 的选项就很有帮助了!让我们来做几个简单的测试,包括实体的文件系统挂载与 /proc 这个虚拟文件系统的内容,看看有多少的进程对这些挂载点或其他目录的使用状态吧!
# 范例二:找到所有使用到 /proc 这个文件系统的进程吧!
[root@study ~]# fuser -uv /proc
/proc: root kernel mount (root)/proc
rtkit 768 .rc.. (rtkit)rtkit-daemon
# 数据量还不会很多,虽然这个目录很繁忙~没关系!我们可以继续这样作,看看其他的进程!
[root@study ~]# fuser -mvu /proc
USER PID ACCESS COMMAND
/proc: root kernel mount (root)/proc
root 1 f.... (root)systemd
root 2 ...e. (root)kthreadd
.....(底下省略).....
# 有这几支进程在进行 /proc 文件系统的存取喔!这样清楚了吗?
# 范例三:找到所有使用到 /home 这个文件系统的进程吧!
[root@study ~]# echo $$
31743 # 先确认一下,自己的 bash PID 号码吧!
[root@study ~]# cd /home
[root@study home]# fuser -muv .
USER PID ACCESS COMMAND
/home: root kernel mount (root)/home
dmtsai 31535 ..c.. (dmtsai)bash
root 31571 ..c.. (root)passwd
root 31737 ..c.. (root)sudo
root 31743 ..c.. (root)bash # 果然,自己的 PID 在啊!
[root@study home]# cd ~
[root@study ~]# 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@study ~]# fuser -mki /home
/home: 31535c 31571c 31737c # 你会发现, PID 跟上面查到的相同!
Kill process 31535 ? (y/N) # 这里会问你要不要删除!当然不要乱删除啦!通通取消!
既然可以针对整个文件系统,那么能不能仅针对单一文件啊?当然可以啰!看一下底下的案例先:
# 范例四:找到 /run 底下属于 FIFO 类型的文件,并且找出存取该文件的进程
[root@study ~]# find /run -type p
.....(前面省略).....
/run/systemd/sessions/165.ref
/run/systemd/sessions/1.ref
/run/systemd/sessions/c1.ref # 随便抓个项目!就是这个好了!来测试一下!
[root@study ~]# fuser -uv /run/systemd/sessions/c1.ref
USER PID ACCESS COMMAND
/run/systemd/sessions/c1.ref:
root 763 f.... (root)systemd-logind
root 5450 F.... (root)gdm-session-wor
# 通常系统的 FIFO 文件都会放置到 /run 底下,透过这个方式来追踪该文件被存取的 process!
# 也能够晓得系统有多忙碌啊!呵呵!
如何?很有趣的一个指令吧!透过这个 fuser 我们可以找出使用该文件、目录的进程,藉以观察的啦!他的重点与 ps, pstree 不同。 fuser 可以让我们了解到某个文件 (或文件系统) 目前正在被哪些进程所利用!
相对于 fuser 是由文件或者装置去找出使用该文件或装置的进程,反过来说,如何查出某个进程开启或者使用的文件与装置呢?呼呼!那就是使用 lsof 啰~
[root@study ~]# lsof [-aUu] [+d]
选项与参数:
-a :多项数据需要『同时成立』才显示出结果时!
-U :仅列出 Unix like 系统的 socket 文件类型;
-u :后面接 username,列出该使用者相关进程所开启的文件;
+d :后面接目录,亦即找出某个目录底下已经被开启的文件!
# 范例一:列出目前系统上面所有已经被开启的文件与装置:
[root@study ~]# 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 也有显示出来喔!
# 范例二:仅列出关于 root 的所有进程开启的 socket 文件
[root@study ~]# lsof -u root -a -U
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
systemd 1 root 3u unix 0xffff8800b7756580 0t0 13715 socket
systemd 1 root 7u unix 0xffff8800b7755a40 0t0 1902
@/org/freedesktop/systemd1/notify
systemd 1 root 9u unix 0xffff8800b7756d00 0t0 1903 /run/systemd/private
.....(中间省略).....
Xorg 4496 root 1u unix 0xffff8800ab107480 0t0 25981 @/tmp/.X11-unix/X0
Xorg 4496 root 3u unix 0xffff8800ab107840 0t0 25982 /tmp/.X11-unix/X0
Xorg 4496 root 16u unix 0xffff8800b7754f00 0t0 25174 @/tmp/.X11-unix/X0
.....(底下省略).....
# 注意到那个 -a 吧!如果你分别输入 lsof -u root 及 lsof -U ,会有啥信息?
# 使用 lsof -u root -U 及 lsof -u root -a -U ,呵呵!都不同啦!
# -a 的用途就是在解决同时需要两个项目都成立时啊! ^_^
# 范例三:请列出目前系统上面所有的被启动的周边装置
[root@study ~]# lsof +d /dev
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
systemd 1 root 0u CHR 1,3 0t0 1028 /dev/null
systemd 1 root 1u CHR 1,3 0t0 1028 /dev/null
# 看吧!因为装置都在 /dev 里面嘛!所以啰,使用搜寻目录即可啊!
# 范例四:秀出属于 root 的 bash 这支程序所开启的文件
[root@study ~]# lsof -u root | grep bash
ksmtuned 781 root txt REG 253,0 960384 33867220 /usr/bin/bash
bash 13888 root cwd DIR 253,0 4096 50331777 /root
bash 13888 root rtd DIR 253,0 4096 128 /
bash 13888 root txt REG 253,0 960384 33867220 /usr/bin/bash
bash 13888 root mem REG 253,0 106065056 17331169 /usr/lib/locale/locale-archive
....(底下省略)....
这个指令可以找出您想要知道的某个进程是否有启用哪些信息
?例如上头提到的范例四的执行结果呢!
[root@study ~]# pidof [-sx] program_name
选项与参数:
-s :仅列出一个 PID 而不列出所有的 PID
-x :同时列出该 program name 可能的 PPID 那个进程的 PID
# 范例一:列出目前系统上面 systemd 以及 rsyslogd 这两个程序的 PID
[root@study ~]# pidof systemd rsyslogd
1 742
# 理论上,应该会有两个 PID 才对。上面的显示也是出现了两个 PID 喔。
# 分别是 systemd 及 rsyslogd 这两支程序的 PID 啦。
很简单的用法吧,透过这个 pidof 指令,并且配合 ps aux 与正规表示法,就可以很轻易的找到您所想要的进程内容了呢。 如果要找的是 bash ,那就 pidof bash ,立刻列出一堆 PID 号码了
[root@node-135 ~]# ps aux | grep `pidof rsyslogd`
root 963 0.0 0.3 239124 6084 ? Ssl Aug10 1:01 /usr/sbin/rsyslogd -n
该系列目录 --> 【BASH】回顾与知识点梳理(目录)