我们在linux下执行的命令,除了shell内置命令,大部分命令都有对应的二进制可执行程序(program)文件,这些命令被称为shell外置命令。
大部分时候这些二进制可执行程序文件静静的存在于磁盘目录中,一旦命令被执行, 命令对应的二进制可执行程序文件就会被加载到内存中运行,变成可被linux内核调度的进程(program)。
在内存中运行的程序(program)称为进程(program)。命令执行完毕,进程也就是退出了。
linux启动后,在运行的过程中,有非常多常驻内存的服务进程在后台运行,这些在后台运行的服务进程称为系统守护进程。
进程是操作系统上非常重要的概念,进程的调度管理也是linux内核最基本最重要的功能之一。 本章就来了解linux下的进程管理。

1.什么是进程(process)

回到顶部

简单来说,进程就是在内存中运行的程序,linux内核为每一个进程分配一个ID,称为PID(进程ID). 我们前面讲过文件权限的概念,一个用户对一个文件的读写执行权限,都和文件的权限属性相关。 那么系统是怎么判断权限的呢?linux会为每个进程分配对应的实际用户(组)ID、有效用户(组)ID和保存的设置用户(组)ID,这些组成了进程的权限属性。 实际上linux正是通过用户所触发进程的有效用户(组)ID来和文件权限属性来进行匹配判断的。
我们以通过cat命令读取/etc/passwd文件为例,简单介绍linux进程,以及进程在权限判断中所承担的角色。
假设当前系统登录用户为peter,/etc/passwd文件的权限属性如下所示:

              [peter@initroot ~]# ls -l /etc/passwd
              -rw-r--r-- 1 root root 2589 Jan  7 14:54 /etc/passwd              
              
很明显peter用户对/etc/passwd文件来说是其他用户other,peter对该文件的权限为r--,只能读取该文件。
我们通过whereis命令查找到cat命令对应的二进制可执行程序文件,并通过ls -l命令查看该文件的权限属性:
                [peter@initroot ~]# whereis cat
                cat: /bin/cat /usr/share/man/man1/cat.1.gz
                [peter@initroot ~]# ls -l /bin/cat 
                -rwxr-xr-x 1 root root 35064 Jan 18  2018 /bin/cat
              
cat命令的二进制可执行程序文件为/bin/cat, peter用户对/bin/cat文件来说是其他用户other,对该文件的权限为r-x,可以读取和执行该文件。 也就是说peter用户有权限运行cat命令。于是peter在shell命令行下输入cat /etc/passwd命令。
我们在前面讲解过linux命令的执行原理。此时,shell会产生一个子进程,该子进程会将cat命令对应的二进制可执行程序文件/bin/cat加载到内存中运行,子进程变为cat进程。 因为是peter用户触发的cat进程并且/bin/cat文件没有设置用户(组)ID位,所以系统会将cat进程的实际用户ID和有效用户ID设置为peter的用户ID。
cat进程在打开并读取/etc/passwd文件的时候,就会和/etc/passwd文件相应的权限属性进行匹配判断, 我们这个例子中cat的有效用户ID为peter的用户ID,很明显cat进程有权限读取/etc/passwd, 于是cat进程读取/etc/passwd文件并将文件内容输出到屏幕,最后cat进程退出,回到shell命令行。
以上就是cat命令读取/etc/passwd文件的大概过程,以及linux是如何进程权限判断的。 这里面涉及到的一些概念,特别是实际用户(组)ID、有效用户(组)ID和保存的设置用户(组)ID,我们会在后面详细介绍。

2.进程与程序(process & program)

回到顶部

通过上面的描述,我们已经非常详细的给出了程序和进程的概念了。 程序就是二进制可执行程序文件,通常存储在磁盘目录中。 程序被加载到内存后就被称为进程。进程就是在内存中运行的程序。
程序和进程其实就是同一段计算机执行指令集合的两种不同存在形式。 他们其实是一个东西的两种称呼,在磁盘中就叫程序,加载到内存后就叫进程了。 每个进程都有唯一的标识符称为进程ID,即PID。系统通过PID识别进程。 有一些进程是用户在shell命令行下执行命令而触发的。 还有些常驻内存的进程,这些进程运行在后台,不需要控制台终端,随linux系统启动而被加载运行,这类进程被称为linux守护进程。
不同用户执行同一个程序而产生的进程,会取得不同的权限属性,例如我们上面peter执行cat命令, 那么产生的cat进程的实际用户(组)ID和有效用户(组)ID就是peter的用户(组)ID。 root的用户(组)ID为0,UID/GID = 0/0,如果是root执行cat命令,那么产生的cat进程的实际用户(组)ID和有效用户(组)ID就是0了,cat进程就会拥有root的权限了。
再比如每个用户在登录的时候,都会取得一个登录shell,可以通过/etc/passwd文件每行的最后一个字段查看每个用户的登录shell的可执行文件路径。 大部分用户包括root的登录shell可执行程序文件为/bin/bash。
用户登录后,login进程会通过/etc/passwd文件获得用户登录shell的可执行文件路径/bin/bash,将shell的二进制可执行程序文件/bin/bash加载到内存中,自此shell进程便产生了。
而这个登录shell的权限属性就对应了相应的登录用户的权限属性。例如登录用户为peter,那么shell进程的实际用户(组)ID和有效用户(组)ID就是peter的用户(组)ID。 而当用户在该登录shell中执行命令而产生的所有子进程,也都会继承shell的权限属性。
另外进程的权限属性还和二进制可执行程序文件的设置用户(组)ID位有关,关于文件的设置用户(组)ID位我们在讲解文件权限属性的时候已经提到过,稍后我们还会对相关知识进行讲解。
实际上,linux下所有的用户进程都是由一个进程衍生出来的,那就是init进程,init进程是系统开启的第一个用户进程,此后的所有用户进程都是有init进程分化出来。 例如init进程会产生login进程,login进程用来提示用户登录,用户登录后login进程就会产生出shell进程,用户在shell命令行下执行命令,例如上面的cat命令,shell就会产生相应的命令进程。 上面init进程是login进程的父进程,login进程就是shell进程的父进程,shell进程又是cat进程的父进程。反过来cat进程是shell进程的子进程,shell进程是login进程的子进程, login进程是init进程的子进程。这样进程之间就会存在父子关系,每个进程都会有一个父进程,一个进程可能会产生一个或多个子进程,拥有共同父进程的进程互为兄弟进程。 从任何一个进程往上就会追溯到init进程,init进程是所有进程的祖先。系统中所有的进程就会形成一个以init进程为树根的树状进程家谱。 可以通过pstree命令查看系统中所有进程组成的父子进程树。
我们刚才提到shell进程是登录用户登录后,由login进程产生的进程,shell进程就是login进程的子进程。shell的二进制可执行文件为/bin/bash, 那么我可不可以在shell命令行下再执行shell呢?答案是肯定的。在命令行下执行一个二进制可执行文件,只需要提供该文件的路径就可以了。
不过/bin/bash文件所在的目录已经存在$PATH环境变量中了,所以只需要在bash下直接输入bash就可以启动另一个shell了,相当于bash也是一个命令了。
同理,login进程和init进程也有对应的命令,例如可以在shell下输入login命令,系统就会给出登录提示,该命令需要root权限。
输入init命令就会重启进入不同的运行级别,关于init命令我们后面会详细介绍。
除了刚才提到的pstree命令,还可以通过ps命令观察系统中运行的进程信息。 这里先做个简单的演示,后面会详细讲解ps和pstree命令。
在命令行下输入bash命令,启动另一个bash。

              [peter@initroot ~]# bash
            
这样我们就进入到子进程bash的环境中了,在新bash的命令行下输入ps -l命令:
              [peter@initroot ~]# ps -l
              F S   UID   PID  PPID  C PRI  NI ADDR SZ WCHAN  TTY          TIME CMD
              0 S  1000  1743  1736  0  80   0 -  6115 wait   pts/0    00:00:00 bash
              0 S  1000  3126  1743  0  80   0 -  6116 wait   pts/0    00:00:00 bash
              4 R  1000  3135  3126  0  80   0 -  7663 -      pts/0    00:00:00 ps
            
从上面的输出中,可以看出每个进程都有很多信息字段,我们主要关注PID和PPID这两个字段,其中PID为进程的ID,PPID为进程的父进程ID。 我们可以看到ps进程的PPID为3126,第二个进程的PID为3126,所以第二个bash进程就是ps进程的父进程。 第二个bash进程的PPID为1743,而第一个进程的PID为1743,所以第一个bash进程就是第二个bash进程的父进程。 这样这三个进程就组成了父子关系:bash(1743)---bash(3126)----ps(3135)。
我们通过pstree -p命令即可观察到这种父子关系:
              [peter@initroot ~]# pstree -p
              ...省略...gnome-terminal-(1736)─┬─bash(1743)───bash(3126)───pstree(3164)
            
上述省略掉了部分输出,注意看上面的bash(3126)的子进程变成了pstree(3164),因为我们执行的是pstree命令,所以就变成pstree进程了。 另外bash(1743)的父进程不应该是login进程吗? 怎么是gnome-terminal-(1736)这样一个进程呢? 我们上面一直在说是login进程启动了bash进程,其实上面描述的是从本地机器通过命令行模式登录的情形。 这里是在图形用户界面模式下通过terminal工具运行的命令,所以如果你平时是通过terminal来学习linux命令,那么bash进程其实就是由terminal进程启动的。 可以通过ctrl+alt+[F1-F7]快捷键切换到命令行终端,登陆后运行pstree -p命令,就会发现登录bash是有login进程启动的:
              [peter@initroot ~]# pstree -p
              ...省略...login(6643)───bash(7068)───bash(7543)───pstree(7553)
            
如果你是通过ssh远程登录的linux主机,那么就会发现bash进程是由sshd进程启动的:
              [peter@initroot ~]# pstree -p
              ...省略...sshd(23900)───bash(23904)───bash(23951)───pstree(23964)
            
直接输入exit即可退出当前bash。
上述两个bash进程的关系如下图所示: 父子bash进程关系 我们经常遇到这样的问题,有时候一个进程占用的内存空间太大,而这个进程在系统中可有可无。通常我们会用kill -9命令将该进程杀掉, 但是过了一段时间后,你会发现这个被杀掉的进程又出来了,严重托慢了系统的运行效率,真的非常让人恼火。 如果排除了crontab的原因,那么大部分可能的原因就是该进程是被父进程启动的,我们只需要找到这个进程的父进程,然后再酌情处理就可以了,比如将父进程也杀掉就可以了。

1.程序与进程

回到顶部

通过前面的讲解,我们大致了解了linux命令的来龙去脉,不管是linux命令,还是bash shell,都是计算机程序软件,都有自己的可执行程序文件。 这些可执行程序文件大部分都由c/c++程序设计语言编写的源程序代码文件通过编译链接而来. 这些可执行程序文件都存放在磁盘的某个目录中。根据计算机原理我们知道,计算机程序需要加载到内存中才能由cpu执行。 bash shell的可执行程序文件/bin/bash是什么时候加载到内存的呢? 大部分情况下bash shell是在操作系统启动后,用户登录以后就会将bash shell可执行程序文件加载到内存中执行,而负责用户登录的程序是login。 所以登录shell是由login进程启动的。 这里提到login进程?为什么不说login程序呢? 我们将存放在磁盘目录中的程序可执行文件称为程序,而程序一旦加载进内存,就成为进程了。 可以认为进程就是运行中的程序.

3.命令执行过程fork and exec

回到顶部

我们在前面很多地方已经多次提到一条shell外置命令的执行过程了,简单来说你在shell命令行下输入一条命令,shell会创建一个新的子进程, 子进程将命令对应的二进制可执行程序文件加载到内存中执行,shell创建一个新子进程的过程叫fork,fork为分叉分支的意思,创建新进程也就是创建一个新的分支 进程加载二进制可执行程序文件到内存的过程称为exec,exec为execute的缩写,表示加载执行的意思,所以整个流程称为fork-and-exec流程。 linux子进程加载执行新程序采用写时复制技术:
(1)shell先fork出一个和自己一模一样的子进程,除了父子进程的PID和PPID不同外!此时子进程中的程序代码数据和父进程shell一模一样。
(2)子进程exec加载执行命令对应的二进制可执行程序文件,将子进程中的执行代码替换为新的执行代码;
系统或网络服务:常驻在内存的进程 到目前为止,我们接触的大部分命令的执行过程都很快,例如ls、touch、rm、mkdir、cp、mv、chmod、chown、passwd等等, 这些命令执行完就结束了。也就是说这些命令执行所产生的进程很快就会终止退出,并不会一直占用内存。 linux里面还有很多进程,这些进程随linux系统的启动而被加载运行,此后便会一直常驻在内存中, 除非linux关机或者崩溃死机,否则这些进程就会一直在内存中运行,这些进程运行在后台,不需要控制台终端,这类进程被称为linux守护进程(daemon)。
一般linux守护进程大多是提供某种系统服务功能的进程,这些服务进程的名字都会在可执行文件名的基础上加上d,表示daemon的意思。 例如需要周期扫瞄/etc/crontab文件而执行例行性工作的crond和atd,提供系统日功能的rsyslogd等。 另外还有很多提供网络服务(server)功能的daemon进程,例如提供域名服务的named,提供www服务的nginx和apache,提供邮件服务的postfix,提供ftp服务的vsftpd, 提供远程连接服务的sshd等等,这些服务进程都是我们后面在服务器运维中经常见到的守护进程,也是linux服务器运维工作的基础和重点。 这些网络服务进程在开启后都会监听某个网络端口(port),以便客户端(client)可以连接相应的服务。

4.进程角度理解Linux的多用户多任务多终端环境

回到顶部

了解了linux进程,应该对linux的多人多用户机制有了更深的理解。不同的用户登陆后,都会启动该用户相对应的登录shell进程, 而不同用户的shell进程在启动的时候,都可以读取相应用户的shell环境配置文件~/.bashrc,从而每个用户都可以根据自己的喜好设置shell环境。
不同用户启动的进程都具有该用户相应的权限。 linux中运行的进程都是相互独立的,除非进程间存在通信机制,否则每个进程在内存中都是独立运行的,互不干扰。 linux通过进程调度确保每个进程都能得到公平的运行,所以即使系统中有多个用户, 但是对每个用户而言就像是自己在独占这台linux主机,看上去这台linux主机就只有自己在使用一样。
同样,我们前面提到过通过ctrl+alt+[F1-F7]组合键可以切换linux的多终端窗口,也是通过多进程实现的。每个虚拟终端就是一个tty进程。 我们可以通过配置设置tty虚拟终端的个数,也就是设置系统启动的tty进程个数。这方面的内容我们会在开启启动流程中介绍。 linux的多终端对进程管理也有很大帮助,比如我们在某个终端界面下系统死机了,怎么动都动不了,做什么都没有反应。 这时候可以尝试用ctrl+alt+[F1-F7]组合键切换到其他的终端机界面,然后用ps和top等进程管理工具找出使系统出错的那个进程, 然后使用kill命令杀掉该进程。最后再回到刚才出错的终端界面,基本就可以回复正常了。

1.linux查看系统进程运行状态

回到顶部

思考如下问题: 1.linux系统下运行着非常多的进程,如果系统资源非常紧张,如何找出做消耗系统资源的进程? 2.如果某个进程发生了错误,怎么找到这个错误进程并将其从linux系统中删除呢? 3.你可能希望某项工作能够快点运行完毕,如何让进程可以优先运行呢?
上面这些问题都涉及到进程的管理问题。
一个称职的linux系统管理员,必须要熟悉进程的管理流程才行,否则当系统发生问题时,还真的束手无策了! 下面我们就来详细了解系统的进程管理!
有很多命令可以查看系统中运行进程的状态信息,这些工具有ps、pstree和top等。其中ps和pstree可以静态的显示系统进程状态, 而top可以实时的动态显示系统进程的状态信息。
既然进程这么重要,那么我们如何查阅系统上面正在运作当中的进程呢?很简单啊! 利用静态的 ps 或者是动态的 top,还能以 pstree 来查阅进程树之间的关系喔!

二.查看系统进程的状态信息

回到顶部

思考如下问题: 1.linux系统下运行着非常多的进程,如果系统资源非常紧张,如何找出做消耗系统资源的进程? 2.如果某个进程发生了错误,怎么找到这个错误进程并将其从linux系统中删除呢? 3.你可能希望某项工作能够快点运行完毕,如何让进程可以优先运行呢?
上面这些问题都涉及到进程的管理问题。
一个称职的linux系统管理员,必须要熟悉进程的管理流程才行,否则当系统发生问题时,还真的束手无策了! 下面我们就来详细了解系统的进程管理!
有很多命令可以查看系统中运行进程的状态信息,这些工具有ps、pstree和top等。其中ps和pstree可以静态的显示系统进程状态, 而top可以实时的动态显示系统进程的状态信息。
既然进程这么重要,那么我们如何查阅系统上面正在运作当中的进程呢?很简单啊! 利用静态的 ps 或者是动态的 top,还能以 pstree 来查阅进程树之间的关系喔!

1.ps打印当前时刻进程的运行状态

回到顶部

ps命令常用的命令格式如下所示:

              [root@initroot ~]# ps aux #观察系统所有的进程数据
              [root@initroot ~]# ps -lA #也是能够观察所有系统的数据
              [root@initroot ~]# ps axjf #连同部分进程树状态
            
选项与参数:
-A :显示系统中所有的进程,与-e具有同样的效用;
-a :显示具有控制终端(terminal)的进程;
-u :有效用户(effective user)相关的process;
x :通常与a选项一起使用,可列出进程的较完整信息。
输出格式规划:
l :显示进程的详细信息;
j :工作的格式(jobs format);
-f :做一个更为完整的输出。
ps默认只列出当前bash进程及其相关进程的信息,相关进程大多是bash的子进程。-l选项可以列出更加详细的进程信息。 更为常用的是显示系统中所有的进程状态信息ps aux.
只列出当前bash进程和相关进程信息:
              [peter@initroot ~]# ps -l
              F S   UID   PID  PPID  C PRI  NI ADDR SZ WCHAN  TTY          TIME CMD
              0 S  1000  2062  2056  0  80   0 -  6277 wait   pts/0    00:00:00 bash
              4 R  1000  5109  2062  0  80   0 -  7663 -      pts/0    00:00:00 ps
            
上述输出的各字段含义如下所示:
F:进程标志(process flags),常见号码有:
4表示此进程的权限为root;
1则表示此子进程仅进行复制(fork)而没有实际执行(exec)。
S:进程的状态(STAT),主要的状态有:
R (Running):该程序正在运作中;
S (Sleep):该程序目前正处在睡眠状态(idle),但可以被唤醒(signal)。
D :不可被唤醒的睡眠状态,通常进程可能在等待I/O
T :停止状态(stop),可能是在工作控制(背景暂停)或被追踪(traced)状态;
Z :僵尸(Zombie)状态,进程已经终止,但是尸体还留在内存中,需要父进程来收尸。
UID:进程的用户ID;
PID:进程ID;
PPID:进程的父进程ID;
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的缩写,触发此进程的命令。
bash进程的UID为0,这是普通用户peter的UID,也就是说这条进程是用户peter的进程。如果当前用户root,并且进程是由root触发的,那么进程的UID就是0了。 bash进程的状态为S睡眠(sleep), 之所以为睡眠因为他触发了ps(状态为run) 之故。PID为2062,,优先级为80, bash进程的终端接口为 pts/0 ,运行状态为等待(wait)
上面的输出可以看出当前bash环境只有两个进程,bash和ps,由于我们是在当前bash环境下执行的ps命令,所以理所当然ps进程就是bash进程的子进程了。 我们看到ps进程的PPID为2062,这正是bash进程的PID。也可通过pstree命令观察ps和bash进程的父子关系。
注意ps命令列出的是ps命令执行的那个时刻点的进程信息。 其实ps命令执行的非常快,在显示完上述信息后,这个ps进程就已经结束了。 如果我们再次执行ps -l,会发现ps进程的PID已经不是5109了,说明这是一个新的ps进程,而刚才的ps进程在输出信息后就已经结束退出了。 因为我们是在同一个bash下执行的ps命令,所以产生的ps进程的父进程都是一样的,就是当前的bash进程了,所以你会发现不管执行多少个ps -l命令, ps进程的PID一直在变化,而PPID一直没有变化。
ps -l只列出了两个进程,没什么意思啊,没啥感觉啊。我们继续作一下,干一票大的。当前登录用户是peter,我们通过su -将用户切换为root, 然后在命令行下执行一个wget下载任务,下载linux内核文件,然后再执行ps -l观察进程信息:
              [peter@initroot ~]# su -
              Password: 
              [root@initroot:~]# nohup wget -c https://git.kernel.org/torvalds/t/linux-5.5-rc6.tar.gz > /dev/null 2>&1 &
              [1] 5097
              [root@initroot ~]# ps -l
              F S   UID   PID  PPID  C PRI  NI ADDR SZ WCHAN  TTY          TIME CMD
              4 S     0  4911  2062  0  80   0 - 21370 wait   pts/0    00:00:00 su
              4 S     0  4924  4911  0  80   0 -  6100 wait   pts/0    00:00:00 bash
              0 S     0  5097  4924  0  80   0 - 10615 poll_s pts/0    00:00:00 wget
              4 R     0  5098  4924  0  80   0 -  7663 -      pts/0    00:00:00 ps
            
我们通过su -切换到root用户,然后在后台执行了一个wget下载任务,关于这条下载命令我们会在后面详细解释。 再次通过ps -l命令观察就会发现多了几个进程,仔细观察会发现bash进程的PID发生了变化,刚才是2062,现在怎么变成4924了?而su进程的PPID是2062. 我们通过每个进程的PID和PPID仔细梳理就会发现这些进程之间的父子关系为:bash(2062)--su(4911)--bash(4924)--wget(5097)、ps(5098). 原来这是两个不同的bash,也就是说我们通过su命令进入了另一个bash环境,这两个bash进程是爷孙关系。 这里注意我们通过wget下载的文件非常大,所以wget进程一时半会儿还不会结束,假如这个时候我用exit命令退出了当前的bash(4924)环境回到刚才的bash(2062)环境, 那么su(4911)进程及其子进程bash(4924)就会结束退出,这对于wget(5097)进程是一个极度悲伤的事情,因为老爸bash(4924)进程和老爹su(4911)进程都相继去世了。 而兄弟ps(5098)进程也早早的结束了自己的使命归天了。其实上面如果我们在执行下载命令的时候不加上nohup,那么wget(5097)进程也会因为悲伤过度而去世。 而加上nohup后,wget(5097)进程就可以坚强的活了下来,但是因为父进程已经去世了,所以wget(5097)进程就变成孤儿进程。
              [root@initroot ~]# exit
              [peter@initroot ~]# su -
              Password: 
              [root@initroot ~]:~# ps -l
              F S   UID   PID  PPID  C PRI  NI ADDR SZ WCHAN  TTY          TIME CMD
              0 S     0  5097  1174  3  80   0 - 10648 wait_w pts/0    00:00:07 wget
              4 S     0  5112  2062  0  80   0 - 21370 wait   pts/0    00:00:00 su
              4 S     0  5113  5112  0  80   0 -  6100 wait   pts/0    00:00:00 bash
              4 R     0  5126  5113  0  80   0 -  7663 -      pts/0    00:00:00 ps
            
我们发现su(5112)、bash(5113)、ps(5126)已经不是刚才的su(4911)、bash(4924)、ps(5098),对于wget(5097)进程来说,真是物是人非啊。 但是奇怪的是,wget(5097)进程的PPID居然变成1174了?父进程不是去世了吗?怎么又有PPID了呢? 原来我们可怜的wget(5097)进程被进程ID为1174的进程收养了!通过ps aux命令我们找到PID为1174的进程,原来是/lib/systemd/systemd进程, 也就是说系统中的孤儿进程会被/lib/systemd/systemd进程收养。以前的linux系统,孤儿进程会被1号进程init收养。 ps默认只能列出和当前bash进程相关的进程,使用ps aux可以列出系统中目前在内存中的所有进程信息:
              [root@initroot ~]# ps aux
              USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
              root         1  0.0  0.2 191024  2588 ?        Ss    2019   4:26 /usr/lib/systemd/systemd --switched-root --system --deserialize 22
              root         2  0.0  0.0      0     0 ?        S     2019   0:00 [kthreadd]
              root         3  0.0  0.0      0     0 ?        S     2019   1:04 [ksoftirqd/0]
              root         5  0.0  0.0      0     0 ?        S<    2019   0:00 [kworker/0:0H]
              root         7  0.0  0.0      0     0 ?        S     2019   0:00 [migration/0]
              root         8  0.0  0.0      0     0 ?        S     2019   0:00 [rcu_bh]
              root         9  0.0  0.0      0     0 ?        R     2019  23:00 [rcu_sched]
              root        10  0.0  0.0      0     0 ?        S<    2019   0:00 [lru-add-drain]
              root        11  0.0  0.0      0     0 ?        S     2019   0:26 [watchdog/0]
              root        13  0.0  0.0      0     0 ?        S     2019   0:00 [kdevtmpfs]
              root        14  0.0  0.0      0     0 ?        S<    2019   0:00 [netns]
              root        15  0.0  0.0      0     0 ?        S     2019   0:01 [khungtaskd]
              root        16  0.0  0.0      0     0 ?        S<    2019   0:00 [writeback]
              root        17  0.0  0.0      0     0 ?        S<    2019   0:00 [kintegrityd]
              root        18  0.0  0.0      0     0 ?        S<    2019   0:00 [bioset]
              root        19  0.0  0.0      0     0 ?        S<    2019   0:00 [bioset]
              root        20  0.0  0.0      0     0 ?        S<    2019   0:00 [bioset]
              root        21  0.0  0.0      0     0 ?        S<    2019   0:00 [kblockd]
              root        22  0.0  0.0      0     0 ?        S<    2019   0:00 [md]
              root        23  0.0  0.0      0     0 ?        S<    2019   0:00 [edac-poller]
              root        24  0.0  0.0      0     0 ?        S<    2019   0:00 [watchdogd]
              root        30  0.0  0.0      0     0 ?        S     2019   2:17 [kswapd0]
              root        31  0.0  0.0      0     0 ?        SN    2019   0:00 [ksmd]
              root        32  0.0  0.0      0     0 ?        SN    2019   0:11 [khugepaged]
              root        33  0.0  0.0      0     0 ?        S<    2019   0:00 [crypto]
              root        41  0.0  0.0      0     0 ?        S<    2019   0:00 [kthrotld]
              root        43  0.0  0.0      0     0 ?        S<    2019   0:00 [kmpath_rdacd]
              root        44  0.0  0.0      0     0 ?        S<    2019   0:00 [kaluad]
              root        45  0.0  0.0      0     0 ?        S<    2019   0:00 [kpsmoused]
              root        46  0.0  0.0      0     0 ?        S<    2019   0:00 [ipv6_addrconf]
              root        59  0.0  0.0      0     0 ?        S<    2019   0:00 [deferwq]
              root       102  0.0  0.0      0     0 ?        S     2019   0:00 [kauditd]
              root       236  0.0  0.0      0     0 ?        S<    2019   0:00 [ata_sff]
              root       247  0.0  0.0      0     0 ?        S     2019   0:00 [scsi_eh_0]
              root       248  0.0  0.0      0     0 ?        S<    2019   0:00 [scsi_tmf_0]
              root       249  0.0  0.0      0     0 ?        S     2019   0:00 [scsi_eh_1]
              root       250  0.0  0.0      0     0 ?        S<    2019   0:00 [scsi_tmf_1]
              root       255  0.0  0.0      0     0 ?        S<    2019   0:00 [ttm_swap]
              root       261  0.0  0.0      0     0 ?        S<    2019   1:43 [kworker/0:1H]
              root       271  0.0  0.0      0     0 ?        S     2019   2:11 [jbd2/vda1-8]
              root       272  0.0  0.0      0     0 ?        S<    2019   0:00 [ext4-rsv-conver]
              root       339  0.0  0.3  47324  3356 ?        Ss    2019   0:33 /usr/lib/systemd/systemd-journald
              root       357  0.0  0.0  44484   908 ?        Ss    2019   0:00 /usr/lib/systemd/systemd-udevd
              root       458  0.0  0.0      0     0 ?        S<    2019   0:00 [nfit]
              root       460  0.0  0.0  55520   856 ?        S<sl  2019   0:08 /sbin/auditd
              dbus       487  0.0  0.1  58108  1272 ?        Ss    2019   3:09 /usr/bin/dbus-daemon --system --address=systemd: --nofork --nopidfile --systemd-activation
              ntp        492  0.0  0.1  47276  1412 ?        Ss    2019   0:32 /usr/sbin/ntpd -u ntp:ntp -g
              polkitd    496  0.0  1.0 612328 10392 ?        Ssl   2019   0:20 /usr/lib/polkit-1/polkitd --no-debug
              root       497  0.0  0.1  26612  1372 ?        Ss    2019   1:21 /usr/lib/systemd/systemd-logind
              root       501  0.0  0.1 126284  1088 ?        Ss    2019   0:14 /usr/sbin/crond -n
              root       506  0.0  0.0  25904   312 ?        Ss    2019   0:00 /usr/sbin/atd -f
              root       530  0.0  0.0 110104   364 ttyS0    Ss+   2019   0:00 /sbin/agetty --keep-baud 115200,38400,9600 ttyS0 vt220
              root       531  0.0  0.0 110104   372 tty1     Ss+   2019   0:00 /sbin/agetty --noclear tty1 linux
              root       717  0.0  0.2 107464  2048 ?        Ss    2019   0:00 /sbin/dhclient -1 -q -lf /var/lib/dhclient/dhclient--eth0.lease -pf /var/run/dhclient-eth0.pid -H izm5e94e7bypr5rhnhbvq9z eth0
              root       782  0.0  1.1 573932 11976 ?        Ssl   2019  12:54 /usr/bin/python2 -Es /usr/sbin/tuned -l -P
              root       791  0.0  0.5 352880  5568 ?        Ssl   2019   5:32 /usr/sbin/rsyslogd -n
              root       797  0.0  0.3  41072  3200 ?        Ssl   2019  49:59 /usr/sbin/aliyun-service
              mysql      927  0.0  0.0 113308   584 ?        Ss    2019   0:00 /bin/sh /usr/bin/mysqld_safe --basedir=/usr
              mysql     1193  0.0 11.6 1189784 118372 ?      Sl    2019  60:40 /usr/libexec/mysqld --basedir=/usr --datadir=/var/lib/mysql --plugin-dir=/usr/lib64/mysql/plugin --log-error=/var/log/mariadb/mariadb.log --pid
              root      1242  0.0  0.1 112864  1560 ?        Ss    2019   0:01 /usr/sbin/sshd -D
              root      2530  0.0  0.2  32528  2232 ?        S<sl  2019  34:34 /usr/local/aegis/aegis_update/AliYunDunUpdate
              root      2586  2.8  1.7 139372 17268 ?        S<sl  2019 2508:22 /usr/local/aegis/aegis_client/aegis_10_75/AliYunDun
              apache    3290  0.0  1.8 401376 19016 ?        S     2019   1:33 php-fpm: pool www
              ...部分省略...
              root     10351  0.0  0.5 390312  5404 ?        Ss    2019   3:10 php-fpm: master process (/etc/php-fpm.conf)
              ...部分省略...
              root     10373  0.0  0.2 125876  2320 ?        Ss    2019   0:00 nginx: master process /usr/sbin/nginx
              nginx    10374  0.0  0.7 129004  7620 ?        S     2019   5:18 nginx: worker process
              ...部分省略...
              root     15615  0.0  0.0      0     0 ?        S    Jan07   0:00 [kworker/u2:1]
              root     15728  0.0  2.3 734928 24344 ?        Sl   Jan07   0:00 npm
              root     15741  0.0  7.2 872332 73268 ?        Sl   Jan07   1:47 node /home/wwwroot/default/kblog/node_modules/.bin/nuxt start
              apache   27911  0.0  1.9 403656 19652 ?        S     2019   2:48 php-fpm: pool www
              apache   28122  0.0  1.9 403640 19444 ?        S     2019   2:48 php-fpm: pool www
              root     30895  0.0  0.0      0     0 ?        S    08:40   0:00 [kworker/u2:2]
              root     31200  0.0  0.5 157388  6052 ?        Ss   10:49   0:00 sshd: root@notty
              root     31202  0.0  0.3  72336  3064 ?        Ss   10:49   0:00 /usr/libexec/openssh/sftp-server
              root     31547  0.0  0.0      0     0 ?        S    12:30   0:00 [kworker/0:0]
              root     31589  0.0  0.5 157404  6052 ?        Ss   12:43   0:00 sshd: root@notty
              root     31591  0.0  0.2  72268  2940 ?        Ss   12:43   0:00 /usr/libexec/openssh/sftp-server
              root     31611  0.0  0.0      0     0 ?        R    13:00   0:00 [kworker/0:1]
              root     31624  0.2  0.5 157256  6020 ?        Ss   13:07   0:00 sshd: root@pts/0
              root     31626  0.0  0.2 115572  2128 pts/0    Ss   13:07   0:00 -bash
              root     31641  0.0  0.1 155360  1932 pts/0    R+   13:07   0:00 ps aux
            
ps aux输出的各字段和ps -l的输出有所不同,pa aux输出的各字段的意义为:
USER:该 process 的用户帐号名
PID :该 process 的进程PID;
%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的顺序来排序显示。我们以为上面的bash进程为例说明,该进程的执行用户为root,进程PID为31626,占用了0.2%的内存容百分比,状态为休眠(S), 该进程启动的时间为13:07,如果进程启动运行的时间很久,就不会列出实际的启动时间。这个bash是我刚刚通过ssh远程连接而启动的bash进程,控制终端为pts/0。
使用ps -lA列出所有的进程信息
              [root@initroot ~]# ps -lA
              F S   UID   PID  PPID  C PRI  NI ADDR SZ WCHAN  TTY          TIME CMD
              4 S     0     1     0  0  80   0 - 47756 ep_pol ?        00:04:26 systemd
              1 S     0     2     0  0  80   0 -     0 kthrea ?        00:00:00 kthreadd
              1 S     0     3     2  0  80   0 -     0 smpboo ?        00:01:04 ksoftirqd/0
              ...(省略)...
            
每个字段与 ps -l 的输出情况相同,但显示的进程则包括系统所有的进程。
使用ps axjf以树状结构显示进程:
              [root@initroot ~]# ps axjf
              PPID   PID  PGID   SID TTY      TPGID STAT   UID   TIME COMMAND
                0     2     0     0 ?           -1 S        0   0:00 [kthreadd]
                2     3     0     0 ?           -1 S        0   1:04  \_ [ksoftirqd/0]
                2     5     0     0 ?           -1 S<       0   0:00  \_ [kworker/0:0H]
                2     7     0     0 ?           -1 S        0   0:00  \_ [migration/0]
                2     8     0     0 ?           -1 S        0   0:00  \_ [rcu_bh]
                2     9     0     0 ?           -1 R        0  23:00  \_ [rcu_sched]
                ...(省略)...
              1242 31200 31200 31200 ?           -1 Ss       0   0:00  \_ sshd: root@notty
              31200 31202 31202 31202 ?           -1 Ss       0   0:00  |   \_ /usr/libexec/openssh/sftp-server
              1242 31589 31589 31589 ?           -1 Ss       0   0:00  \_ sshd: root@notty
              31589 31591 31591 31591 ?           -1 Ss       0   0:00  |   \_ /usr/libexec/openssh/sftp-server
              1242 31624 31624 31624 ?           -1 Ss       0   0:00  \_ sshd: root@pts/0
              31624 31626 31626 31626 pts/0    31675 Ss       0   0:00      \_ -bash
              31626 31675 31675 31626 pts/0    31675 R+       0   0:00          \_ ps axjf
              ...(省略)...
            
很多时候我们都是通过ssh远程登录的方式取得bash环境的,通过上面的进程关系也可以看出来。 还可以使用pstree命令来显示进程之间的父子关系。其他各字段的意义可以man ps
找出与cron与rsyslog这两个服务进程的PID:
              [root@initroot ~]# ps aux | egrep '(cron|rsyslog)'
              root       501  0.0  0.1 126284  1088 ?        Ss    2019   0:14 /usr/sbin/crond -n
              root       791  0.0  0.5 352880  5568 ?        Ssl   2019   5:32 /usr/sbin/rsyslogd -n
              root     31693  0.0  0.1 112708  1052 pts/0    R+   13:28   0:00 grep -E --color=auto (cron|rsyslog)
            
可以看出crond进程的pid为501, rsyslogd进程的pid为791。 僵尸(zombie)进程是什么? 通常,造成僵尸进程的成因是因为该进程应该已经执行完毕,或者是因故应该要终止了, 但是该进程的父进程却无法完整的将该进程结束掉,而造成那个进程一直存在内存当中。
如果你发现在某个进程的 CMD 后面还接上<defunct> 时,就代表该进程是僵尸进程啦,例如:
              apache 8683 0.0 0.9 83384 9992 ? Z 14:33 0:00 /usr/sbin/httpd <defunct>
            
当系统不稳定的时候就容易造成所谓的僵尸进程,可能是因为程序写的不好啦,或者是使用者的操作习惯不良等等所造成。 如果你发现系统中很多僵尸进程时,记得啊!要找出该进程的父进程, 然后好好的做个追踪,好好的进行主机的环境优化啊! 看看有什么地方需要改善的,不要只是直接将他kill掉而已呢!不然的话,万一他一直产生,那可就麻烦了!
事实上,通常僵尸进程都已经无法控管,而直接是交给systemd进程来负责了,偏偏 systemd是系统第一支执行的程序, 他是所有程序的父程序! 我们无法杀掉该程序的 (杀掉他,系统就死掉了!),所以啰,如果产生僵尸进程, 而系统过一阵子还没有办法透过核心非经常性的特殊处理来将该进程删除时,那你只好透过reboot的方式来将该进程抹去了!

ps命令查看进程信息

ps
ps -aux
ps -elf

七.与进程相关的其他命令

回到顶部
还有一些与进程有关的命令可以值得参考与应用

1.fuser找出正在使用某个文件的进程

回到顶部

当你在删除某个文件时,这个文件却被某个进程占用着,这时候是不能删除的。那么怎么找到占用该文件的进程呢? 或者你用umount卸载某个文件系,却出现了device is busy的提示,这表明文件系统正在被某个进程使用。 这时候就可以使用fuser命令了。fuser语法有点像这样:

              [root@initroot ~]# fuser [-umv] [-k [i] [-signal]] file/dir
            
选项与参数:
-u :除了进程的PID之外,同时列出该进程的拥有者;
-m :该文件所在的文件系统,后面接的那个文件名会主动的上提到该文件系统的最顶层,对umount不成功很有效!
-v :可以列出每个文件与进程还有指令的完整相关性!
-k :向找到的进程发送信号,信号由-signal指定,如果没有指定信号名或者信号编号,默认为SIGKILL信号;
-i :用户交互模式,必须与-k配合,在删除进程之前会先询问使用者!
-signal:例如 -1 -15 等等,若不加的话,默认是 SIGKILL (-9) 啰!
范例一:找出目前所在目录的使用 PID/所属账号/权限 为何? 看看有哪些进程正在使用当前工作目录:
              [root@initroot ~]# fuser -uv .
                                  USER        PID ACCESS COMMAND
              /root:               root       6632 ..c.. (root)bash

            
正在使用当前工作目录的进程为bash进程,进程pid为6632,该进程属于root用户。比较有趣的是ACCESS字段,该字段代表的意义为:
c :此进程在当前的目录下(非次目录);
e :可被触发为执行状态;
f :是一个被开启的文件;
r :代表顶层目录(root directory);
F :该文件被开启了,不过在等待回应中;
m :可能为分享的动态函式库;
-m选项可以查看文件所在的文件系统中有多少进程正在占用该文件系统
找到所有使用/proc这个文件系统的进程吧!
              [root@initroot ~]# fuser -uv /proc
              USER        PID ACCESS COMMAND
              /proc:               root     kernel mount (root)/proc
              rtkit      1436 .rc.. (rtkit)rtkit-daemon
            
数据量还不会很多,虽然这个目录很繁忙~没关系!我们可以继续这样作,看看其他的进程!
              [root@initroot ~]# fuser -mvu /proc
              USER        PID ACCESS COMMAND
              /proc:               root     kernel mount (root)/proc
              root          1 f.... (root)systemd
              root        377 f.... (root)systemd-journal
              systemd-resolve    580 f.... (systemd-resolve)systemd-resolve
              syslog      708 f.... (syslog)rsyslogd
              root        727 f.... (root)udisksd
              root        964 F.... (root)Xorg
              peter      1174 f.... (peter)systemd
              peter      1428 f.... (peter)csd-housekeepin
              rtkit      1436 .rc.. (rtkit)rtkit-daemon
              peter      1474 f.... (peter)gvfs-udisks2-vo
              peter      1553 f.... (peter)nemo-desktop
              peter      1609 f.... (peter)gvfsd-trash
              peter      2180 .rc.. (peter)Web Content
              peter      2289 .rc.. (peter)WebExtensions
              peter      2383 .rc.. (peter)Web Content
              peter      3422 f.... (peter)nemo
              peter      3941 .rc.. (peter)Web Content
              peter      4371 f.... (peter)xreader
              peter      4387 f.... (peter)WebKitNetworkPr
              root       6620 f.... (root)systemd
            
有这几支进程在进行 /proc 文件系统的存取喔!这样清楚了吗?
范例三:找到所有使用到 /home 这个文件系统的进程吧!
先确认一下,自己的 bash PID 号码吧!
              [root@initroot ~]# echo $$
              31743
            
              [root@initroot ~]# cd /home
              [root@initroot home]# fuser -muv .
                        USER PID ACCESS COMMAND
              /home:    root kernel mount (root)/home
              peter 31535 ..c.. (peter)bash
              root 31571 ..c.. (root)passwd
              root 31737 ..c.. (root)sudo
              root 31743 ..c.. (root)bash
            
# 果然,自己的 PID 在啊!
              [root@initroot home]# cd ~
              [root@initroot ~]# 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@initroot ~]# fuser -mki /home
              /home:
              31535c 31571c 31737c
              # 你会发现, PID 跟上面查到的相同!
              Kill process 31535 ? (y/N) 
            
# 这里会问你要不要删除!当然不要乱删除啦!通通取消! 既然可以针对整个文件系统,那么能不能仅针对单一文件啊?当然可以啰!
看一下底下的案例先:
范例四:找到 /run 底下属于 FIFO 类型的文件,并且找出存取该文件的进程
              [root@initroot ~]# find /run -type p
              .....(前面省略).....
              /run/systemd/sessions/165.ref
              /run/systemd/sessions/1.ref/run/systemd/sessions/c1.ref
            
# 随便抓个项目!就是这个好了!来测试一下!
              [root@initroot ~]# 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 可以让我们了解到某个文件 (或文件系统) 目前正在被哪些进程所利用!

2.lsof列出进程所打开的文件名

回到顶部

fuser是通过文件名找出占用该文件或者文件系统的进程,而lsof命令则可以查看进程打开的文件或者使用的文件系统。

              [root@initroot ~]# lsof [-aUu] [+d]
            
选项与参数:
-a :多项数据需要同时成立才显示出结果时! -U :仅列出 Unix like 系统的 socket 文件类型; -u :后面接 username,列出该使用者相关进程所开启的文件; +d :后面接目录,亦即找出某个目录底下已经被开启的文件!
列出目前系统上面所有已经被开启的文件与装置:
              [root@initroot ~]# lsof
              lsof: WARNING: can't stat() fuse.gvfsd-fuse file system /run/user/1000/gvfs
                    Output information may be incomplete.
              COMMAND    PID  TID            USER   FD      TYPE             DEVICE  SIZE/OFF       NODE NAME
              systemd      1                 root  cwd       DIR                8,1      4096          2 /
              systemd      1                 root  rtd       DIR                8,1      4096          2 /
              systemd      1                 root  txt       REG                8,1   1595792    1049085 /lib/systemd/systemd
              systemd      1                 root  mem       REG                8,1   1700792    1053812 /lib/x86_64-linux-gnu/libm-2.27.so
              systemd      1                 root  mem       REG                8,1    121016    1049149 /lib/x86_64-linux-gnu/libudev.so.1.6.9
              systemd      1                 root  mem       REG                8,1     84032    1053790 /lib/x86_64-linux-gnu/libgpg-error.so.0.22.0
              systemd      1                 root  mem       REG                8,1     43304    1053801 /lib/x86_64-linux-gnu/libjson-c.so.3.0.1
              systemd      1                 root  mem       REG                8,1     34872     532281 /usr/lib/x86_64-linux-gnu/libargon2.so.0
              ...(省略)...
            
如果不加任何参数,lsof默认会将目前系统上面已经开启的文件全部列出来。可以看到目前系统中打开的文件非常多。可以注意到,第一个文件 systemd 执行的 地方就是根目录,而根目录所在的 inode 也有显示出来了!
仅列出关于 root 的所有进程开启的 socket 文件
              [root@initroot ~]# lsof -u root -a -U
              lsof: WARNING: can't stat() fuse.gvfsd-fuse file system /run/user/1000/gvfs
                    Output information may be incomplete.
              COMMAND    PID USER   FD   TYPE             DEVICE SIZE/OFF   NODE NAME
              systemd      1 root   14u  unix 0xffff8c980d33e400      0t0  14487 /run/systemd/notify type=DGRAM
              systemd      1 root   15u  unix 0xffff8c980d33e800      0t0  14488 type=DGRAM
              systemd      1 root   16u  unix 0xffff8c980d33f400      0t0  14489 type=DGRAM
              systemd      1 root   17u  unix 0xffff8c980d33e000      0t0  14490 /run/systemd/private type=STREAM
              systemd      1 root   18u  unix 0xffff8c980dc44400      0t0  24013 /run/systemd/journal/stdout type=STREAM
              systemd      1 root   19u  unix 0xffff8c980ddb3c00      0t0  24265 /run/systemd/journal/stdout type=STREAM
              systemd      1 root   20u  unix 0xffff8c981625c800      0t0  24329 /run/systemd/journal/stdout type=STREAM
              systemd      1 root   21u  unix 0xffff8c981625d800      0t0  24330 /run/systemd/journal/stdout type=STREAM
              systemd      1 root   23u  unix 0xffff8c981833b400      0t0  23801 /run/systemd/journal/stdout type=STREAM
              systemd      1 root   26u  unix 0xffff8c980d33f000      0t0  14502 /run/systemd/journal/stdout type=STREAM
              systemd      1 root   27u  unix 0xffff8c980d33fc00      0t0  14504 /run/systemd/journal/socket type=DGRAM
              systemd      1 root   32u  unix 0xffff8c980c8d3800      0t0  14543 /run/systemd/coredump type=SEQPACKET
              systemd      1 root   33u  unix 0xffff8c980c8d3c00      0t0  14545 /run/systemd/fsck.progress type=STREAM
              systemd      1 root   34u  unix 0xffff8c980c8d2000      0t0  14547 /run/udev/control type=SEQPACKET
              systemd      1 root   35u  unix 0xffff8c980c8d3400      0t0  14550 /run/systemd/journal/dev-log type=DGRAM
              systemd      1 root   37u  unix 0xffff8c980c8d2400      0t0  14559 /run/lvm/lvmpolld.socket type=STREAM
              systemd      1 root   38u  unix 0xffff8c980c8d2c00      0t0  14563 /run/systemd/journal/syslog type=DGRAM
              systemd      1 root   44u  unix 0xffff8c9816219000      0t0  14569 /run/lvm/lvmetad.socket type=STREAM
              systemd      1 root   46u  unix 0xffff8c980ddb2800      0t0  15354 type=DGRAM
              systemd      1 root   48u  unix 0xffff8c980dfbf800      0t0  16711 /run/systemd/journal/stdout type=STREAM
              ...(省略)...
            
注意到那个 -a 吧!如果你分别输入 lsof -u root 及 lsof -U ,会有啥信息?
使用 lsof -u root -U 及 lsof -u root -a -U ,呵呵!都不同啦!-a 的用途就是在解决同时需要两个项目都成立时啊! ^_^
列出目前系统上面所有的被启动的设备:
              [root@initroot ~]# lsof +d /dev
              lsof: WARNING: can't stat() fuse.gvfsd-fuse file system /run/user/1000/gvfs
                    Output information may be incomplete.
              COMMAND    PID            USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
              systemd      1            root    0u   CHR    1,3      0t0    6 /dev/null
              systemd      1            root    1u   CHR    1,3      0t0    6 /dev/null
              systemd      1            root    2u   CHR    1,3      0t0    6 /dev/null
              systemd      1            root    3w   CHR   1,11      0t0   12 /dev/kmsg
              systemd      1            root   24r   CHR 10,235      0t0  402 /dev/autofs
              systemd      1            root   70u   CHR  10,62      0t0    4 /dev/rfkill
              kdevtmpfs   15            root  cwd    DIR    0,6     4080    2 /dev
              kdevtmpfs   15            root  rtd    DIR    0,6     4080    2 /dev
              systemd-j  377            root    0r   CHR    1,3      0t0    6 /dev/null
              systemd-j  377            root    1w   CHR    1,3      0t0    6 /dev/null
              systemd-j  377            root    2w   CHR    1,3      0t0    6 /dev/null
              systemd-j  377            root    7w   CHR   1,11      0t0   12 /dev/kmsg
              systemd-j  377            root    9u   CHR   1,11      0t0   12 /dev/kmsg
              lvmetad    405            root    0r   CHR    1,3      0t0    6 /dev/null
              systemd-u  407            root    0r   CHR    1,3      0t0    6 /dev/null
              systemd-r  580 systemd-resolve    0r   CHR    1,3      0t0    6 /dev/null
              dbus-daem  586      messagebus    0u   CHR    1,3      0t0    6 /dev/null
            
# 看吧!因为装置都在 /dev 里面嘛!所以啰,使用搜寻目录即可啊!
秀出属于 root 的 bash 进程所开启的文件
              [root@initroot ~]# lsof -u root | grep bash
              lsof: WARNING: can't stat() fuse.gvfsd-fuse file system /run/user/1000/gvfs
                    Output information may be incomplete.
              bash      6632 root  cwd       DIR                8,1     4096    2621441 /root
              bash      6632 root  rtd       DIR                8,1     4096          2 /
              bash      6632 root  txt       REG                8,1  1113504    4456451 /bin/bash
              bash      6632 root  mem       REG                8,1    47568    1053839 /lib/x86_64-linux-gnu/libnss_files-2.27.so
              bash      6632 root  mem       REG                8,1    97176    1053833 /lib/x86_64-linux-gnu/libnsl-2.27.so
              bash      6632 root  mem       REG                8,1    47576    1053850 /lib/x86_64-linux-gnu/libnss_nis-2.27.so
              bash      6632 root  mem       REG                8,1    39744    1053835 /lib/x86_64-linux-gnu/libnss_compat-2.27.so
              bash      6632 root  mem       REG                8,1  4795856     531033 /usr/lib/locale/locale-archive
              bash      6632 root  mem       REG                8,1  2030544    1053749 /lib/x86_64-linux-gnu/libc-2.27.so
              bash      6632 root  mem       REG                8,1    14560    1053772 /lib/x86_64-linux-gnu/libdl-2.27.so
              bash      6632 root  mem       REG                8,1   170784    1053907 /lib/x86_64-linux-gnu/libtinfo.so.5.9
              bash      6632 root  mem       REG                8,1   170960    1053721 /lib/x86_64-linux-gnu/ld-2.27.so
              bash      6632 root  mem       REG                8,1    26376     790981 /usr/lib/x86_64-linux-gnu/gconv/gconv-modules.cache
              bash      6632 root    0u      CHR              136,0      0t0          3 /dev/pts/0
              bash      6632 root    1u      CHR              136,0      0t0          3 /dev/pts/0
              bash      6632 root    2u      CHR              136,0      0t0          3 /dev/pts/0
              bash      6632 root  255u      CHR              136,0      0t0          3 /dev/pts/0
            
这个指令可以找出您想要知道的某个进程是否有启用哪些信息!

3.pidof通过进程名打印进程的PID

回到顶部

              [root@initroot ~]# pidof [-sx] program_name
            
选项与参数:
-s :仅列出一个PID而不列出所有的PID
-x :同时列出该program name可能的PPID那个进程的PID
列出目前系统上面systemd以及rsyslogd这两个进程的PID
              [root@initroot ~]# pidof systemd rsyslogd
              6620 1174 708
            
# 理论上,应该会有两个 PID 才对。上面的显示也是出现了两个 PID 喔。 # 分别是 systemd 及 rsyslogd 这两支程序的 PID 啦。
很简单的用法吧,透过这个 pidof 指令,并且配合 ps aux 与正规表示法,就可以很轻易的找到您所想要的进程内容了呢。 如果要找的是bash ,那就 pidof bash ,立刻列出一堆PID号码了~

2.top观察进程状态的动态变化

回到顶部

我们上面通过ps观察进程的状态,其实只是在执行ps命令那个时间点的进程状态信息。 如果进程的状态发生变化,通过ps命令是无法感知到的,除非持续不断的执行ps来观察进程的状态改变。但是这样真的太麻烦了,即麻烦又不现实。 而通过top命令我们就可以很容易的持续观察系统中进程的状态变化。top命令常用格式如下:

              [root@initroot ~]# top [-d 数字] | top [-bnp]
            
选项与参数:
-d: 后面接数字,单位为秒, 表示top刷新的时间频率。默认是5秒;
-b: 以批次的方式执行top, 还有更多的参数可以使用喔! 通常会搭配数据流重导向来将批次的结果输出成为文件。
-n: 与-b搭配,意义是,需要进行几次top的输出结果。
-p: 指定某些个PID来进行观察监测而已。
其实 top 的功能非常多!可以用的按键也非常的多!可以参考 man top 的内部说明文件! 这里仅是列出一些自己常用的选项而已。 利用top观察系统运行状态信息:
              [root@initroot ~]# top

              top - 13:43:33 up  4:25,  1 user,  load average: 0.58, 0.47, 0.47
              Tasks: 182 total,   2 running, 148 sleeping,   0 stopped,   1 zombie
              %Cpu(s): 15.4 us,  2.5 sy,  0.0 ni, 81.5 id,  0.4 wa,  0.0 hi,  0.0 si,  0.0 st
              KiB Mem :  5069456 total,   276332 free,  2437764 used,  2355360 buff/cache
              KiB Swap:  2097148 total,  2096880 free,      268 used.  2300408 avail Mem 

                PID USER      PR  NI    VIRT    RES    SHR S %CPU %MEM     TIME+ COMMAND                                                                                                                                                                    
                10 root      20   0       0      0      0 R  6.2  0.0   0:16.85 rcu_sched                                                                                                                                                                  
                964 root      20   0  643264 159536  87232 S  6.2  3.1   2:55.09 Xorg                                                                                                                                                                       
                  1 root      20   0  159856   9104   6684 S  0.0  0.2   0:01.16 systemd                                                                                                                                                                    
                  2 root      20   0       0      0      0 S  0.0  0.0   0:00.00 kthreadd                                                                                                                                                                   
                  3 root       0 -20       0      0      0 I  0.0  0.0   0:00.00 rcu_gp                                                                                                                                                                     
                  4 root       0 -20       0      0      0 I  0.0  0.0   0:00.00 rcu_par_gp                                                                                                                                                                 
                  6 root       0 -20       0      0      0 I  0.0  0.0   0:00.00 kworker/0:0H-kb                                                                                                                                                            
                  8 root       0 -20       0      0      0 I  0.0  0.0   0:00.00 mm_percpu_wq                                                                                                                                                               
                  9 root      20   0       0      0      0 S  0.0  0.0   0:01.82 ksoftirqd/0                                                                                                                                                                
                11 root      rt   0       0      0      0 S  0.0  0.0   0:00.04 migration/0                                                                                                                                                                
                12 root     -51   0       0      0      0 S  0.0  0.0   0:00.00 idle_inject/0                                                                                                                                                              
                13 root      20   0       0      0      0 I  0.0  0.0   0:00.00 kworker/0:1-eve                                                                                                                                                            
                14 root      20   0       0      0      0 S  0.0  0.0   0:00.00 cpuhp/0                                                                                                                                                                    
                15 root      20   0       0      0      0 S  0.0  0.0   0:00.00 kdevtmpfs                                                                                                                                                                  
                16 root       0 -20       0      0      0 I  0.0  0.0   0:00.00 netns                                                                                                                                                                      
                17 root      20   0       0      0      0 S  0.0  0.0   0:00.00 rcu_tasks_kthre                                                                                                                                                            
                18 root      20   0       0      0      0 S  0.0  0.0   0:00.00 kauditd                                                                                                                                                                    
                19 root      20   0       0      0      0 S  0.0  0.0   0:00.01 khungtaskd                                                                                                                                                                 
                20 root      20   0       0      0      0 S  0.0  0.0   0:00.00 oom_reaper                                                                                                                                                                 
                21 root       0 -20       0      0      0 I  0.0  0.0   0:00.00 writeback                                                                                                                                                                  
                22 root      20   0       0      0      0 S  0.0  0.0   0:00.00 kcompactd0                                                                                                                                                                 
                23 root      25   5       0      0      0 S  0.0  0.0   0:00.00 ksmd                                                                                                                                                                       
                24 root      39  19       0      0      0 S  0.0  0.0   0:00.00 khugepaged                                                                                                                                                                 
                25 root       0 -20       0      0      0 I  0.0  0.0   0:00.00 crypto                                                                                                                                                                     
                26 root       0 -20       0      0      0 I  0.0  0.0   0:00.00 kintegrityd                                                                                                                                                                
                27 root       0 -20       0      0      0 I  0.0  0.0   0:00.00 kblockd                                                                                                                                                                    
                28 root       0 -20       0      0      0 I  0.0  0.0   0:00.00 tpm_dev_wq                                                                                                                                                                 
                29 root       0 -20       0      0      0 I  0.0  0.0   0:00.00 ata_sff                                                                                                                                                                    
                30 root       0 -20       0      0      0 I  0.0  0.0   0:00.00 md                                                                                                                                                                         
                31 root       0 -20       0      0      0 I  0.0  0.0   0:00.00 edac-poller                                                                                                                                                                
                32 root       0 -20       0      0      0 I  0.0  0.0   0:00.00 devfreq_wq                                                                                                                                                                 
                33 root      rt   0       0      0      0 S  0.0  0.0   0:00.00 watchdogd                                                                                                                                                                  
                37 root      20   0       0      0      0 S  0.0  0.0   0:00.11 kswapd0                                                                                                                                                                    
                38 root       0 -20       0      0      0 I  0.0  0.0   0:00.00 kworker/u3:0                                                                                                                                                               
                39 root      20   0       0      0      0 S  0.0  0.0   0:00.00 ecryptfs-kthrea                                                                                                                                                            
                128 root       0 -20       0      0      0 I  0.0  0.0   0:00.00 kthrotld                                                                                                                                                                   
                129 root       0 -20       0      0      0 I  0.0  0.0   0:00.00 acpi_thermal_pm                                                                                                                                                            
                130 root      20   0       0      0      0 S  0.0  0.0   0:00.01 scsi_eh_0                                                                                                                                                                  
                131 root       0 -20       0      0      0 I  0.0  0.0   0:00.00 scsi_tmf_0                                                                                                                                                                 
                132 root      20   0       0      0      0 S  0.0  0.0   0:00.00 scsi_eh_1                                                                                                                                                                  
                133 root       0 -20       0      0      0 I  0.0  0.0   0:00.00 scsi_tmf_1                                                                                                                                                                 
                136 root       0 -20       0      0      0 I  0.0  0.0   0:00.00 ipv6_addrconf                                                                                                                                                              
                147 root       0 -20       0      0      0 I  0.0  0.0   0:00.00 kstrp                                                                                                                                                                      
                166 root       0 -20       0      0      0 I  0.0  0.0   0:00.00 charger_manager                                                                                                                                                            
                167 root       0 -20       0      0      0 I  0.0  0.0   0:01.32 kworker/0:1H-kb                                                                                                                                                            
                210 root      20   0       0      0      0 S  0.0  0.0   0:00.02 scsi_eh_2                                                                                                                                                                  
                211 root       0 -20       0      0      0 I  0.0  0.0   0:00.00 scsi_tmf_2                                                                                                                                                                 
                214 root     -51   0       0      0      0 S  0.0  0.0   0:07.19 irq/18-vmwgfx                                                                                                                                                              
                215 root       0 -20       0      0      0 I  0.0  0.0   0:00.00 ttm_swap                                                                                                                                                                   
                334 root      20   0       0      0      0 S  0.0  0.0   0:00.46 jbd2/sda1-8     
            
不同于 ps 是静态的结果输出, top 这个程序可以持续的监测 整个系统的进程工作状态。top默认会5秒钟刷新一次,可以用-d指定top的刷新时间,例如2秒钟刷新一次:top -d 2。 top显示的画面主要分为上下两个部分,上面部分为整个系统的资源使用状态,下半部分列出了每个进程的状态信息。
仔细观察会发现上下两个部分的中间由空行隔开,其实这个可不止是空行,这还是一个指令提示输入行。 在top界面环境下还可以执行很多按键指令,某些按键指令需要用户输入,这时候这个空行就变成指令参数输入行了。
常用的按键指令有:
? :显示在top当中可以输入的按键指令;
P :以CPU的使用资源排序显示;
M :以Memory的使用资源排序显示;
N :以PID来排序!
T :由该Process使用的CPU时间累积(TIME+)排序。
k :给予某个PID一个讯号(signal)
r :给予某个PID重新制订一个nice值。
q :离开top软件的按键。
基本上总共有六行,显示的内容依序是:
第一行(top...):这一行显示的信息分别为:
o 目前的时间,亦即是 00:53:59 那个项目;
o 开机到目前为止所经过的时间,亦即是 up 6:07, 那个项目;
o 已经登入系统的用户人数,亦即是 3 users, 项目;
o 系统在 1, 5, 15 分钟的平均工作负载。我们在第十五章谈到的 batch 工作方式为负载小于 0.8 就是这个负载啰! 代表的是 1, 5, 15 分钟,系统平均要负责运作几个进程(工作)的意思。 越小代表系统越闲置,若高于 1 得要注意你的系统进程是否太过繁复了!
第二行(Tasks...):显示的是目前进程的总量与个别进程在什么状态(running, sleeping, stopped, zombie)。 比较 需要注意的是最后的 zombie 那个数值,如果不是 0 !好好看看到底是那个 process 变成僵尸了吧?
第三行(%Cpus...):显示的是 CPU 的整体负载,每个项目可使用 ? 查阅。需要特别注意的是 wa 项目,那 个项目代表的是 I/O wait, 通常你的系统会变慢都是 I/O 产生的问题比较大!因此这里得要注意这个项目 耗用 CPU 的资源喔! 另外,如果是多核心的设备,可以按下数字键『1』来切换成不同 CPU 的负载率。
第四行与第五行:表示目前的物理内存与虚拟内存 (Mem/Swap) 的使用情况。 再次重申,要注意的是 swap 的使用量要尽量的少!如果 swap 被用的很大量,表示系统的物理内存实在不足!
第六行:这个是当在 top 程序当中输入指令时,显示状态的地方。
至于top下半部分的画面,则是每个 process状态信息情况。比较需要注意的是:
PID :每个 process 的 ID 啦!
USER:该 process 所属的使用者;
PR :Priority 的简写,进程的优先执行顺序,越小越早被执行;
NI :Nice 的简写,与 Priority 有关,也是越小越早被执行;
%CPU:CPU 的使用率;
%MEM:内存的使用率;
TIME+:CPU 使用时间的累加;
top 默认使用 CPU 使用率 (%CPU) 作为排序的重点,如果你想要使用内存使用率排序,则可以按 下M键, 若要恢复则按下P即可。如果想要离开top则按下q吧!如果你想要将top的结果输出成为文件时, 可以这样做:
将top的信息进行 2 次,然后将结果输出到 /tmp/top.txt
              [root@initroot ~]# top -b -n 2 > /tmp/top.txt
            
这样就可以将 top 的信息存到 /tmp/top.txt 文件中了。
这可以帮助你将某个时段 top 观察到的结果存成文件,可以用在你想要在系统后台底下执行。 由于是后台执行,与终端机的屏幕大小无关,因此可以得到全部的进程画面!
可以指定进程的PID,只观察某个进程的状态。
$$变量为当前进程的PID,可以使用echo显示,然后用top持续观察该进程的状态:
              [root@initroot ~]# echo $$
              6632                                 #bash进程的PID
              [root@initroot ~]# top -d 2 -p 6632

              top - 14:03:04 up  4:44,  1 user,  load average: 0.31, 0.33, 0.34
              Tasks:   1 total,   0 running,   1 sleeping,   0 stopped,   0 zombie
              %Cpu(s): 14.9 us,  4.1 sy,  0.0 ni, 81.0 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
              KiB Mem :  5069456 total,   310236 free,  2405552 used,  2353668 buff/cache
              KiB Swap:  2097148 total,  2096880 free,      268 used.  2330928 avail Mem 

                PID USER      PR  NI    VIRT    RES    SHR S %CPU %MEM     TIME+ COMMAND                                                                                   
              6632 root      20   0   24400   5228   3660 S  0.0  0.1   0:00.02 bash    
            
如果想要在 top 底下进行一些动作呢? 比方说,修改 NI 这个数值呢?可以这样做:
上面的 NI 值是 0 ,想要改成 10 的话?在top 画面当中直接按下 r 之后,会出现如下的图样:
              top - 14:09:31 up  4:51,  1 user,  load average: 0.66, 0.49, 0.39
              Tasks:   1 total,   0 running,   1 sleeping,   0 stopped,   0 zombie
              %Cpu(s): 18.0 us,  4.6 sy,  0.0 ni, 77.3 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
              KiB Mem :  5069456 total,   309052 free,  2406012 used,  2354392 buff/cache
              KiB Swap:  2097148 total,  2096880 free,      268 used.  2328520 avail Mem 
              PID to renice [default pid = 6632]   #这里出现光标提示符,等待用户输入,根据提示输入相应的参数信息即可
                PID USER      PR  NI    VIRT    RES    SHR S %CPU %MEM     TIME+ COMMAND                                                                                   
               6632 root      20   0   24400   5228   3660 S  0.0  0.1   0:00.02 bash 
            
在指令提示行根据指令提示,输入相关参数即可修改进程的优先级。一般来说,如果想要找出最损耗 CPU 资源的那个进程时,大多使用的就是 top 这支程序啦!然后强制以 CPU 使用资源来排序 (在 top 当中按下 P 即可), 就可以很快的知道啦!

top命令可以实时显示系统的运行时信息

3.pstree以树状结构显示系统中进程的父子关系

回到顶部

              [root@initroot ~]# pstree [-A|U] [-up]
            
选项与参数:
-A :各进程树之间的连接以 ASCII 字符来连接;
-U :各进程树之间的连接以万国码的字符来连接。在某些终端接口下可能会有错误;
-p :并同时列出每个 process 的 PID;
-u :并同时列出每个 process 的所属账号名称。
范例一:列出目前系统上面所有的进程树的相关性:
              [root@initroot ~]# pstree
              systemd─┬─AliYunDun───22*[{AliYunDun}]
                      ├─AliYunDunUpdate───3*[{AliYunDunUpdate}]
                      ├─2*[agetty]
                      ├─aliyun-service───2*[{aliyun-service}]
                      ├─atd
                      ├─auditd───{auditd}
                      ├─crond
                      ├─dbus-daemon
                      ├─dhclient
                      ├─mysqld_safe───mysqld───18*[{mysqld}]
                      ├─nginx───nginx
                      ├─npm─┬─node───10*[{node}]
                      │     └─10*[{npm}]
                      ├─ntpd
                      ├─php-fpm───15*[php-fpm]
                      ├─polkitd───6*[{polkitd}]
                      ├─rsyslogd───2*[{rsyslogd}]
                      ├─sshd─┬─2*[sshd───sftp-server]
                      │      ├─sshd───bash
                      │      └─sshd───bash───pstree
                      ├─systemd-journal
                      ├─systemd-logind
                      ├─systemd-udevd
                      └─tuned───4*[{tuned}]
            
              [root@initroot ~]# pstree -A
              systemd-+-AliYunDun---22*[{AliYunDun}]
                      |-AliYunDunUpdate---3*[{AliYunDunUpdate}]
                      |-2*[agetty]
                      |-aliyun-service---2*[{aliyun-service}]
                      |-atd
                      |-auditd---{auditd}
                      |-crond
                      |-dbus-daemon
                      |-dhclient
                      |-mysqld_safe---mysqld---19*[{mysqld}]
                      |-nginx---nginx
                      |-npm-+-node---10*[{node}]
                      |     `-10*[{npm}]
                      |-ntpd
                      |-php-fpm---15*[php-fpm]
                      |-polkitd---6*[{polkitd}]
                      |-rsyslogd---2*[{rsyslogd}]
                      |-sshd-+-2*[sshd---sftp-server]
                      |      |-sshd---bash
                      |      `-sshd---bash---pstree
                      |-systemd-journal
                      |-systemd-logind
                      |-systemd-udevd
                      `-tuned---4*[{tuned}]
            
# 注意一下,为了节省版面,所以已经删去很多进程了!
范例二:承上题,同时秀出 PID 与 users
              [root@initroot ~]# pstree -Aup
              systemd(1)-+-AliYunDun(2586)-+-{AliYunDun}(2587)
                        |                 |-{AliYunDun}(2588)
                        |                 |-{AliYunDun}(2599)
                        |                 |-{AliYunDun}(2600)
                        |                 |-{AliYunDun}(2601)
                        |                 |-{AliYunDun}(2602)
                        |                 |-{AliYunDun}(2603)
                        |                 |-{AliYunDun}(2604)
                        |                 |-{AliYunDun}(2605)
                        |                 |-{AliYunDun}(2606)
                        |                 |-{AliYunDun}(2607)
                        |                 |-{AliYunDun}(2608)
                        |                 |-{AliYunDun}(2609)
                        |                 |-{AliYunDun}(2610)
                        |                 |-{AliYunDun}(2611)
                        |                 |-{AliYunDun}(2612)
                        |                 |-{AliYunDun}(2613)
                        |                 |-{AliYunDun}(2614)
                        |                 |-{AliYunDun}(2615)
                        |                 |-{AliYunDun}(2616)
                        |                 |-{AliYunDun}(30927)
                        |                 `-{AliYunDun}(32115)
                        |-AliYunDunUpdate(2530)-+-{AliYunDunUpdate}(2531)
                        |                       |-{AliYunDunUpdate}(2532)
                        |                       `-{AliYunDunUpdate}(2534)
                        |-agetty(530)
                        |-agetty(531)
                        |-aliyun-service(797)-+-{aliyun-service}(838)
                        |                     `-{aliyun-service}(842)
                        |-atd(506)
                        |-auditd(460)---{auditd}(461)
                        |-crond(501)
                        |-dbus-daemon(487,dbus)
                        |-dhclient(717)
                        |-mysqld_safe(927,mysql)---mysqld(1193)-+-{mysqld}(1203)
                        |                                       |-{mysqld}(1205)
                        |                                       |-{mysqld}(1206)
                        |                                       |-{mysqld}(1207)
                        |                                       |-{mysqld}(1208)
                        |                                       |-{mysqld}(1209)
                        |                                       |-{mysqld}(1210)
                        |                                       |-{mysqld}(1211)
                        |                                       |-{mysqld}(1212)
                        |                                       |-{mysqld}(1213)
                        |                                       |-{mysqld}(1214)
                        |                                       |-{mysqld}(1217)
                        |                                       |-{mysqld}(1218)
                        |                                       |-{mysqld}(1219)
                        |                                       |-{mysqld}(1220)
                        |                                       |-{mysqld}(1221)
                        |                                       |-{mysqld}(1222)
                        |                                       `-{mysqld}(1240)
                        |-nginx(10373)---nginx(10374,nginx)
                        |-npm(15728)-+-node(15741)-+-{node}(15742)
                        |            |             |-{node}(15743)
                        |            |             |-{node}(15744)
                        |            |             |-{node}(15745)
                        |            |             |-{node}(15746)
                        |            |             |-{node}(15747)
                        |            |             |-{node}(15748)
                        |            |             |-{node}(15749)
                        |            |             |-{node}(15750)
                        |            |             `-{node}(15751)
                        |            |-{npm}(15729)
                        |            |-{npm}(15730)
                        |            |-{npm}(15731)
                        |            |-{npm}(15732)
                        |            |-{npm}(15733)
                        |            |-{npm}(15734)
                        |            |-{npm}(15736)
                        |            |-{npm}(15737)
                        |            |-{npm}(15738)
                        |            `-{npm}(15739)
                        |-ntpd(492,ntp)
                        |-php-fpm(10351)-+-php-fpm(3290,apache)
                        |                |-php-fpm(8272,apache)
                        |                |-php-fpm(9137,apache)
                        |                |-php-fpm(10353,apache)
                        |                |-php-fpm(10354,apache)
                        |                |-php-fpm(10355,apache)
                        |                |-php-fpm(10356,apache)
                        |                |-php-fpm(10357,apache)
                        |                |-php-fpm(12432,apache)
                        |                |-php-fpm(12433,apache)
                        |                |-php-fpm(13209,apache)
                        |                |-php-fpm(13392,apache)
                        |                |-php-fpm(13399,apache)
                        |                |-php-fpm(27911,apache)
                        |                `-php-fpm(28122,apache)
                        |-polkitd(496,polkitd)-+-{polkitd}(509)
                        |                      |-{polkitd}(511)
                        |                      |-{polkitd}(513)
                        |                      |-{polkitd}(514)
                        |                      |-{polkitd}(515)
                        |                      `-{polkitd}(521)
                        |-rsyslogd(791)-+-{rsyslogd}(822)
                        |               `-{rsyslogd}(843)
                        |-sshd(1242)-+-sshd(31589)---sftp-server(31591)
                        |            |-sshd(32116)---bash(32118)
                        |            |-sshd(32277)---sftp-server(32279)
                        |            `-sshd(32423)---bash(32429)---pstree(32464)
                        |-systemd-journal(339)
                        |-systemd-logind(497)
                        |-systemd-udevd(357)
                        `-tuned(782)-+-{tuned}(1108)
                                      |-{tuned}(1111)
                                      |-{tuned}(1115)
                                      `-{tuned}(1215)
            
在括号 () 内的即是 PID 以及该进程的 owner 喔!一般来说,如果该进程的所有人与父进程同, 就不会列出,但是如果与父进程不一样,那就会列出该进程的拥有者!看上面 13927 就转变成 peter 了 如果要找进程之间的相关性,这个 pstree 真是好用到不行!直接输入 pstree 可以查到进程相关性, 如上表所示,还会使用线段将相关性进程连结起来哩! 一般链接符号可以使用 ASCII 码即可,但 有时因为语系问题会主动的以 Unicode 的符号来链接, 但因为可能终端机无法支持该编码,或许会 造成乱码问题。因此可以加上 -A 选项来克服此类线段乱码问题。
由 pstree 的输出我们也可以很清楚的知道,所有的进程都是依附在 systemd 这支进程底下的! 仔 细看一下,这支进程的 PID 是一号喔!因为他是由 Linux 核心所主动呼叫的第一支程序!所以 PID 就是一号了。 这也是我们刚刚提到僵尸进程时有提到,为啥发生僵尸进程需要重新启动? 因为 systemd 要重新启动,而重新启动 systemd 就是 reboot 啰!
如果还想要知道 PID 与所属使用者,加上 -u 及 -p 两个参数即可。我们前面不是一直提到, 如果 子进程挂点或者是老是砍不掉子进程时,该如何找到父进程吗?呵呵!用这个 pstree 就对了! ^_^

pstree命令以树状结构显示系统中的进程,可以更直观的看出进程之间的父子关系

三.kill或者killall给进程发送信号(signal)

回到顶部

进程之间是可以互相控制的!举例来说,你可以关闭、重新启动服务器软件,服务器软件本身是个进 程, 你既然可以让她关闭或启动,当然就是可以控制该进程啦!那么进程是如何互相管理的呢?其 实是透过给予该进程一个讯号 (signal) 去告知该进程你想要让她作什么!因此这个讯号就很重要啦! 我们也在本章之前的 bash 工作管理当中提到过, 要给予某个已经存在背景中的工作某些动作时,是 直接给予一个讯号给该工作号码即可。那么到底有多少 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 吧! 底下分别来看看:
              [root@initroot ~]# kill -signal PID
            
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如 果 你 有 看 到 类 似 『 Aug 5 01:25:02 study rsyslogd: [origin software="rsyslogd" swVersion="7.4.7" x-pid="742" x-info="http://www.rsyslog.com"] rsyslogd was HUPed』之类的字样,就是表示 rsyslogd 在 8/5 有重新启动 (restart) 过了!
了解了这个用法以后,如果未来你想要将某个莫名其妙的登入者的联机删除的话,就可以透过使用 pstree -p 找到相关进程, 然后再以 kill -9 将该进程删除,该条联机就会被踢掉了!这样很简单吧!
killall -signal 指令名称
由于 kill 后面必须要加上 PID (或者是 job number),所以,通常 kill 都会配合 ps, pstree 等指令,因 为我们必须要找到相对应的那个进程的 ID 嘛!但是,如此一来,很麻烦~有没有可以利用『下达指 令的名称』来给予讯号的?举例来说,能不能直接将 rsyslogd 这个进程给予一个 SIGHUP 的讯号呢?
可以的!用 killall 吧!
              [root@initroot ~]# killall [-iIe] [command name]
            
选项与参数:
-i :interactive 的意思,交互式的,若需要删除时,会出现提示字符给用户;
-e :exact 的意思,表示『后面接的 command name 要一致』,但整个完整的指令不能超过 15 个字符。
-I :指令名称(可能含参数)忽略大小写。
范例一:给予 rsyslogd 这个指令启动的 PID 一个 SIGHUP 的讯号
              [root@initroot ~]# killall -1 rsyslogd
            
# 如果用 ps aux 仔细看一下,若包含所有参数,则 /usr/sbin/rsyslogd -n 才是最完整的!
范例二:强制终止所有以 httpd 启动的进程 (其实并没有此进程在系统内)
              [root@initroot ~]# killall -9 httpd
            
范例三:依次询问每个 bash 程序是否需要被终止运作!
              [root@initroot ~]# 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 启动的进程,就会通通的被删除 啦! ^_^16.3.3 关于进程的执行顺序 我们知道 Linux 是多人多任务的环境,由 top 的输出结果我们也发现, 系统同时间有非常多的进程 在运行中,只是绝大部分的进程都在休眠 (sleeping) 状态而已。 想一想,如果所有的进程同时被唤 醒,那么 CPU 应该要先处理那个进程呢?也就是说,那个进程被执行的优先序比较高? 这就得要 考虑到进程的优先执行序 (Priority) 与 CPU 排程啰!
CPU 排程与前一章的例行性工作排程并不一样。 CPU 排程指的是每支进程被 CPU 运作的演算规则, 而例行性工作排程则是将某支程序安排在某个时间再交由系统执行。 CPU 排程与操作系统较 具有相关性!

四.进程优先级Priority和Nice值

回到顶部

我们知道 CPU 一秒钟可以运作多达数 G 的微指令次数,透过核心的 CPU 排程可以让各进程被 CPU 所切换运作, 因此每个进程在一秒钟内或多或少都会被 CPU 执行部分的脚本。如果进程都是 集中在一个队列中等待 CPU 的运作, 而不具有优先级之分,也就是像我们去游乐场玩热门游戏需 要排队一样,每个人都是照顺序来! 你玩过一遍后还想再玩 (没有执行完毕),请到后面继续排队等 待。情况有点像底下这样:
图 16.3.1、并没有优先级的进程队列示意图
上图中假设 pro1, pro2 是紧急的进程, pro3, pro4 是一般的进程,在这样的环境中,由于不具有优 先级, 唉啊!pro1, pro2 还是得要继续等待而没有优待呢!如果 pro3, pro4 的工作又臭又长!那么 紧急的 pro1, pro2 就得要等待个老半天才能够完成!真麻烦啊!所以啰,我们想要将进程分优先级 啦!如果优先序较高则运作次数可以较多次, 而不需要与较慢优先的进程抢位置!我们可以将进程 的优先级与 CPU 排程进行如下图的解释:图 16.3.2、具有优先级的进程队列示意图 如上图所示,具高优先权的 pro1, pro2 可以被取用两次,而较不重要的 pro3, pro4 则运作次数较少。 如此一来 pro1, pro2 就可以较快被完成啦!要注意,上图仅是示意图,并非较优先者一定会被运作 两次啦! 为了要达到上述的功能,我们 Linux 给予进程一个所谓的『优先执行序 (priority, PRI)』, 这个 PRI 值越低代表越优先的意思。不过这个 PRI 值是由核心动态调整的, 用户无法直接调整 PRI 值的。先来瞧瞧 PRI 曾在哪里出现?

              [root@initroot ~]# ps -l
              F S   UID   PID  PPID  C PRI  NI ADDR SZ WCHAN  TTY          TIME CMD
              0 S  1000  1743  1737  0  80   0 -  6115 wait   pts/0    00:00:00 bash
              4 R  1000  3700  1743  0  80   0 -  7663 -      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 值可调整的范围为 -20 ~ 19 ;
root 可随意调整自己或他人进程的 Nice 值,且范围为 -20 ~ 19 ;
一般使用者仅可调整自己进程的 Nice 值,且范围仅为 0 ~ 19 (避免一般用户抢占系统资源);
一般使用者仅可将 nice 值越调越高,例如本来 nice 为 5 ,则未来仅能调整到大于 5;
这也就是说,要调整某个进程的优先执行序,就是『调整该进程的 nice 值』啦!那么如何给予某个 进程 nice 值呢?有两种方式,分别是:
一开始执行程序就立即给予一个特定的 nice 值:用 nice 指令;
调整某个已经存在的 PID 的 nice 值:用 renice 指令。

1.nice :新执行的指令即给予新的 nice 值

回到顶部

              [root@initroot ~]# nice [-n 数字] command
            
选项与参数:
-n:后面接一个数值,数值的范围 -20 ~ 19。
范例一:用 root 给一个 nice 值为 -5 ,用于执行 vim ,并观察该进程!
              [root@initroot ~]# nice -n -5 vim &
              [1] 19865
              [root@initroot ~]# ps -l
              F S
              UID
              PID
              PPID
              C PRI NI ADDR SZ WCHAN TTY
              10 - 29068 wait
              4 S 0 14836 14835 0 90
              4 T 0 19865 14836 0 85
              0 R 0 19866 14836 0 90
              # 原本的 bash PRI 为 90
              pts/0
              5 - 37757 signal pts/0
              10 - 30319 -
              pts/0
              TIME CMD
              00:00:00 bash
              00:00:00 vim
              00:00:00 ps
            
,所以 vim 默认应为 90。不过由于给予 nice 为 -5 ,
因此 vim 的 PRI 降低了!RPI 与 NI 各减 5 !但不一定每次都是正好相同喔!因为核心会动态调整
              [root@initroot ~]# kill -9 %1 #测试完毕将 vim 关闭
            
就如同前面说的, nice 是用来调整进程的执行优先级!这里只是一个执行的范例罢了! 通常什么 时候要将 nice 值调大呢?举例来说,系统的背景工作中, 某些比较不重要的进程之进行:例如备 份工作!由于备份工作相当的耗系统资源, 这个时候就可以将备份的指令之 nice 值调大一些,可 以使系统的资源分配的更为公平!

nice命令用于调整进程的调度优先级

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

回到顶部

              [root@initroot ~]# renice [number] PID
            
选项与参数:
PID :某个进程的 ID 啊!
范例一:找出自己的 bash PID ,并将该 PID 的 nice 调整到 -5
              [root@initroot ~]# 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@initroot ~]# renice -5 14836
              14836 (process ID) old priority 10, new priority -5
              [root@initroot ~]# 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如果要调整的是已经存在的某个进程的话,那么就得要使用 renice 了。使用的方法很简单, renice 后 面接上数值及 PID 即可。因为后面接的是 PID ,所以你务必要以 ps 或者其他进程观察的指令去 找出 PID 才行啊!
由上面这个范例当中我们也看的出来,虽然修改的是 bash 那个进程,但是该进程所触发的 ps 指令 当中的 nice 也会继承而为 -5 喔!了解了吧!整个 nice 值是可以在父进程 --> 子进程之间传递的 呢! 另外,除了 renice 之外,其实那个 top 同样的也是可以调整 nice 值的!

五.进程特殊权限UUID、SUID、SGID

回到顶部

我们在第六章曾经谈到特殊权限的 SUID/SGID/SBIT ,虽然第六章已经将这三种特殊权限作了详细 的解释,不过,我们依旧要来探讨的是,那么到底这些权限对于你的『进程』是如何影响的? 此外, 进程可能会使用到系统资源,举例来说,磁盘就是其中一项资源。哪天你在 umount 磁盘时,系统老 是出现『 device is busy 』的字样~到底是怎么回事啊?我们底下就来谈一谈这些和进程有关系的细 节部分:
SUID 的权限其实与进程的相关性非常的大!为什么呢?先来看看 SUID 的程序是如何被一般用户 执行,且具有什么特色呢?
SUID 权限仅对二进制程序(binary program)有效;
执行者对于该程序需要具有 x 的可执行权限;
本权限仅在执行该程序的过程中有效 (run-time);
执行者将具有该程序拥有者 (owner) 的权限。
所以说,整个 SUID 的权限会生效是由于『具有该权限的程序被触发』,而我们知道一个程序被触 发会变成进程, 所以啰,执行者可以具有程序拥有者的权限就是在该程序变成进程的那个时候啦! 第六章我们还没谈到进程的概念, 所以你或许那时候会觉得很奇怪,为啥执行了 passwd 后你就具 有 root 的权限呢?不都是一般使用者执行的吗? 这是因为你在触发 passwd 后,会取得一个新的进 程与 PID,该 PID 产生时透过 SUID 来给予该 PID 特殊的权限设定啦! 我们使用 peter 登入系 统且执行 passwd 后,透过工作控制来理解一下!

              [peter@study ~]$ passwd
              Changing password for user peter.
              Changing password for peter
              (current) UNIX password: #这里按下 [ctrl]-z 并且按下 [enter]
              [1]+
              Stopped
              passwd
              [peter@study ~]$ pstree -uA
              systemd-+-ModemManager---2*[{ModemManager}]
              ....(中间省略)....
              |-sshd---sshd---sshd(peter)---bash-+-passwd(root)
              |
              ...(底下省略)...
            
`-pstree从上表的结果我们可以发现,底线的部分是属于 peter 这个一般账号的权限,特殊字体的则是 root 的权限! 但你看到了, passwd 确实是由 bash 衍生出来的!不过就是权限不一样!透过这样的解 析, 你也会比较清楚为何不同程序所产生的权限不同了吧!这是由于『SUID 程序运作过程中产生 的进程』的关系啦!
那么既然 SUID/SGID 的权限是比较可怕的,您该如何查询整个系统的 SUID/SGID 的文件呢? 应 该是还不会忘记吧?使用 find 即可啊!
find / -perm /6000

1.什么是proc目录
proc是Linux系统下一个很重要的目录。 它跟/etc, /home等这些系统目录不同, 它不是一个真正的文件系统, 而是一个虚拟的文件系统。
它不存在于磁盘, 而是存在于系统内存中。 所以当你使用 ls -al /proc这条命令来查看proc目录时, 会看到其下面的所有文件的大小都为0字节。
proc以文件系统的方式为访问系统内核的操作提供接口。 很多系统的信息, 如内存使用情况, cpu使用情况,进程信息等等这些信息,都可以通过查看/proc下的对应文件来获得。
proc文件系统是动态从系统内核读出所需信息的。
2. 初识proc目录
proc目录下具体有哪些文件呢?
/proc 目录下的文件
/proc/cpuinifo CPU的信息(型号、家族、缓存大小等)
/proc/meminfo物理内存、交换空间
/proc/mounts 已加载的文件系统的列表
/proc/devices 可用设备的列表
/proc/filesystems 被支持的文件系统
/proc/modules 已加载的模块
/proc/virsion 内核版本
/proc/cmdline 系统启动时输入的内核命令行参数
/proc/XXX XXX是指以进程PID(数字编号)命名的目录,每一个目录表示一个进程(即线程组)。
/proc/swaps 要获知swap空间的使用情况
/proc/uptime 获取系统的正常运行时间
/proc/fs/nfsd/exports 列出由NFS共享的文件系统
/proc/kmsg 该文件被作为内核日志信息源,它可以被作为一个系统信息调用的接口使用
/proc/self -- 到当前进程/proc目录的符号链接,通过这个目录可以获取当前运行进程的信息。
/proc/pci -- 挂接在PCI总线上的设备
/proc/tty/driver/serial --串口配置、统计信息
/proc/version -- 系统版本信息
/proc/sys/kernel/ostype
/proc/sys/kernel/osrelease
/proc/sys/kernel/version
/proc/sys/kernel/hostname -- 主机名
/proc/sys/kernel/domainname -- 域名
/proc/partitions -- 硬盘设备分区信息
/proc/sys/dev/cdrom/info -- CDROM信息
/proc/locks -- 当前系统中所有的文件锁
/proc/loadavg -- 系统负荷信息
/proc/uptime -- 系统启动后的运行时间
3. 从proc窥看系统详情
很多系统命令在读取系统信息的时候,其实是从proc目录下读取对应的文件来获得的。 所以如果我们不使用这些命令, 直接到proc目录下去查看对应文件,也是可以获得对应的信息的。
下面举几个例子:
操作 系统命令 proc对应目录
获取系统版本信息 uname -a 或者 lsb_release /proc/version或者/proc/sys/kernel/hostname[,domainname, osrelease, ostype,version]
获取系统负载信息 top 或者 w 或者 uptime /proc/loadavg
获取内存使用情况 free /proc/meminfo
获取CPU使用情况 top /proc/cpuinfo
获取进程运行情况 ps aux 或者 top /proc/N[N为对应的PID号]
对于查看进程信息一栏,做下补充:
/proc/N pid为N的进程信息
/proc/N/cmdline 进程启动命令
/proc/N/cwd 链接到进程当前工作目录
/proc/N/environ 进程环境变量列表
/proc/N/exe 链接到进程的执行命令文件
/proc/N/fd 包含进程相关的所有的文件描述符
/proc/N/maps 与进程相关的内存映射信息
/proc/N/mem 指代进程持有的内存,不可读
/proc/N/root 链接到进程的根目录
/proc/N/stat 进程的状态
/proc/N/statm 进程使用的内存的状态
/proc/N/status 进程状态信息,比stat/statm更具可读性
/proc/self 链接到当前正在运行的进程
更多的应用场景, 留给大家自己到/proc目录下探索吧。

六./proc目录的意义

回到顶部

其实,我们之前提到的所谓的进程都是在内存当中嘛!而内存当中的数据又都是写入到 /proc/* 这个 目录下的,所以啰,我们当然可以直接观察 /proc 这个目录当中的文件啊! 如果你观察过 /proc 这 个目录的话,应该会发现他有点像这样:

            [root@initroot ~]# ls -al /proc/
            total 4
            dr-xr-xr-x 196 root            root                          0 Jan 19 09:18 .
            drwxr-xr-x  23 root            root                       4096 Jan  7 10:26 ..
            dr-xr-xr-x   9 root            root                          0 Jan 19 09:18 1
            dr-xr-xr-x   9 root            root                          0 Jan 19 15:01 10
            dr-xr-xr-x   9 root            root                          0 Jan 19 15:01 1044
            dr-xr-xr-x   9 root            root                          0 Jan 19 15:01 1055
            dr-xr-xr-x   9 root            root                          0 Jan 19 15:01 11
            dr-xr-xr-x   9 peter           peter                         0 Jan 19 09:20 1174
            ...(省略)...
            dr-xr-xr-x   9 root            root                          0 Jan 19 15:01 920
            dr-xr-xr-x   9 root            root                          0 Jan 19 15:01 937
            dr-xr-xr-x   9 root            root                          0 Jan 19 15:01 949
            dr-xr-xr-x   9 root            root                          0 Jan 19 15:01 964
            dr-xr-xr-x   9 root            root                          0 Jan 19 15:01 966
            dr-xr-xr-x   2 root            root                          0 Jan 19 09:18 acpi
            dr-xr-xr-x   5 root            root                          0 Jan 19 09:18 asound
            -r--r--r--   1 root            root                          0 Jan 19 15:14 buddyinfo
            dr-xr-xr-x   4 root            root                          0 Jan 19 09:18 bus
            -r--r--r--   1 root            root                          0 Jan 19 15:14 cgroups
            -r--r--r--   1 root            root                          0 Jan 19 15:14 cmdline
            -r--r--r--   1 root            root                          0 Jan 19 15:14 consoles
            -r--r--r--   1 root            root                          0 Jan 19 15:14 cpuinfo
            -r--r--r--   1 root            root                          0 Jan 19 15:14 crypto
            -r--r--r--   1 root            root                          0 Jan 19 15:14 devices
            -r--r--r--   1 root            root                          0 Jan 19 15:14 diskstats
            -r--r--r--   1 root            root                          0 Jan 19 15:14 dma
            dr-xr-xr-x   2 root            root                          0 Jan 19 15:14 driver
            -r--r--r--   1 root            root                          0 Jan 19 15:14 execdomains
            -r--r--r--   1 root            root                          0 Jan 19 15:14 fb
            -r--r--r--   1 root            root                          0 Jan 19 15:01 filesystems
            dr-xr-xr-x   5 root            root                          0 Jan 19 09:18 fs
            -r--r--r--   1 root            root                          0 Jan 19 15:14 interrupts
            -r--r--r--   1 root            root                          0 Jan 19 15:14 iomem
            -r--r--r--   1 root            root                          0 Jan 19 15:14 ioports
            dr-xr-xr-x  23 root            root                          0 Jan 19 09:18 irq
            -r--r--r--   1 root            root                          0 Jan 19 15:14 kallsyms
            -r--------   1 root            root            140737477885952 Jan 19 15:14 kcore
            -r--r--r--   1 root            root                          0 Jan 19 15:14 keys
            -r--r--r--   1 root            root                          0 Jan 19 15:14 key-users
            -r--------   1 root            root                          0 Jan 19 09:18 kmsg
            -r--------   1 root            root                          0 Jan 19 15:14 kpagecgroup
            -r--------   1 root            root                          0 Jan 19 15:14 kpagecount
            -r--------   1 root            root                          0 Jan 19 15:14 kpageflags
            -r--r--r--   1 root            root                          0 Jan 19 15:14 loadavg
            -r--r--r--   1 root            root                          0 Jan 19 15:01 locks
            -r--r--r--   1 root            root                          0 Jan 19 15:14 mdstat
            -r--r--r--   1 root            root                          0 Jan 19 14:58 meminfo
            -r--r--r--   1 root            root                          0 Jan 19 15:14 misc
            -r--r--r--   1 root            root                          0 Jan 19 15:14 modules
            lrwxrwxrwx   1 root            root                         11 Jan 19 15:01 mounts -> self/mounts
            -rw-r--r--   1 root            root                          0 Jan 19 09:18 mtrr
            lrwxrwxrwx   1 root            root                          8 Jan 19 15:01 net -> self/net
            -r--r--r--   1 root            root                          0 Jan 19 15:14 pagetypeinfo
            -r--r--r--   1 root            root                          0 Jan 19 15:14 partitions
            dr-xr-xr-x   2 root            root                          0 Jan 19 15:14 pressure
            -r--r--r--   1 root            root                          0 Jan 19 15:14 sched_debug
            -r--r--r--   1 root            root                          0 Jan 19 15:14 schedstat
            dr-xr-xr-x   3 root            root                          0 Jan 19 15:14 scsi
            lrwxrwxrwx   1 root            root                          0 Jan 19 09:18 self -> 8849
            -r--------   1 root            root                          0 Jan 19 15:14 slabinfo
            -r--r--r--   1 root            root                          0 Jan 19 15:14 softirqs
            -r--r--r--   1 root            root                          0 Jan 19 15:14 stat
            -r--r--r--   1 root            root                          0 Jan 19 09:18 swaps
            dr-xr-xr-x   1 root            root                          0 Jan 19 09:18 sys
            --w-------   1 root            root                          0 Jan 19 09:18 sysrq-trigger
            dr-xr-xr-x   2 root            root                          0 Jan 19 15:14 sysvipc
            lrwxrwxrwx   1 root            root                          0 Jan 19 09:18 thread-self -> 8849/task/8849
            -r--------   1 root            root                          0 Jan 19 15:14 timer_list
            dr-xr-xr-x   4 root            root                          0 Jan 19 15:14 tty
            -r--r--r--   1 root            root                          0 Jan 19 15:14 uptime
            -r--r--r--   1 root            root                          0 Jan 19 15:14 version
            -r--r--r--   1 root            root                          0 Jan 19 15:14 version_signature
            -r--------   1 root            root                          0 Jan 19 15:14 vmallocinfo
            -r--r--r--   1 root            root                          0 Jan 19 14:58 vmstat
            -r--r--r--   1 root            root                          0 Jan 19 15:14 zoneinfo
          
基本上,目前主机上面的各个进程的 PID 都是以目录的型态存在于 /proc 当中。 举例来说,我们开机所执行的第一支程序 systemd 他的 PID 是 1 , 这个 PID 的所有相关信息都写入在 /proc/1/*当中! 若我们直接观察 PID 为 1 的数据好了,他有点像这样:
            [root@initroot ~]# ls -al /proc/1
            total 0
            dr-xr-xr-x   9 root root 0 Jan 19 09:18 .
            dr-xr-xr-x 195 root root 0 Jan 19 09:18 ..
            dr-xr-xr-x   2 root root 0 Jan 19 15:02 attr
            -rw-r--r--   1 root root 0 Jan 19 15:16 autogroup
            -r--------   1 root root 0 Jan 19 15:16 auxv
            -r--r--r--   1 root root 0 Jan 19 15:02 cgroup
            --w-------   1 root root 0 Jan 19 15:16 clear_refs
            -r--r--r--   1 root root 0 Jan 19 15:02 cmdline
            -rw-r--r--   1 root root 0 Jan 19 15:02 comm
            -rw-r--r--   1 root root 0 Jan 19 15:16 coredump_filter
            -r--r--r--   1 root root 0 Jan 19 15:16 cpuset
            lrwxrwxrwx   1 root root 0 Jan 19 15:01 cwd -> /
            -r--------   1 root root 0 Jan 19 15:16 environ
            lrwxrwxrwx   1 root root 0 Jan 19 15:01 exe -> /lib/systemd/systemd
            dr-x------   2 root root 0 Jan 19 15:01 fd
            dr-x------   2 root root 0 Jan 19 15:01 fdinfo
            -rw-r--r--   1 root root 0 Jan 19 15:16 gid_map
            -r--------   1 root root 0 Jan 19 15:16 io
            -r--r--r--   1 root root 0 Jan 19 15:16 limits
            -rw-r--r--   1 root root 0 Jan 19 15:02 loginuid
            dr-x------   2 root root 0 Jan 19 15:16 map_files
            -r--r--r--   1 root root 0 Jan 19 15:01 maps
            -rw-------   1 root root 0 Jan 19 15:16 mem
            -r--r--r--   1 root root 0 Jan 19 09:18 mountinfo
            -r--r--r--   1 root root 0 Jan 19 15:16 mounts
            -r--------   1 root root 0 Jan 19 15:16 mountstats
            dr-xr-xr-x   5 root root 0 Jan 19 15:16 net
            dr-x--x--x   2 root root 0 Jan 19 15:16 ns
            -r--r--r--   1 root root 0 Jan 19 15:16 numa_maps
            -rw-r--r--   1 root root 0 Jan 19 15:16 oom_adj
            -r--r--r--   1 root root 0 Jan 19 15:16 oom_score
            -rw-r--r--   1 root root 0 Jan 19 15:16 oom_score_adj
            -r--------   1 root root 0 Jan 19 15:16 pagemap
            -r--------   1 root root 0 Jan 19 15:16 patch_state
            -r--------   1 root root 0 Jan 19 15:16 personality
            -rw-r--r--   1 root root 0 Jan 19 15:16 projid_map
            lrwxrwxrwx   1 root root 0 Jan 19 15:01 root -> /
            -rw-r--r--   1 root root 0 Jan 19 15:16 sched
            -r--r--r--   1 root root 0 Jan 19 15:16 schedstat
            -r--r--r--   1 root root 0 Jan 19 15:02 sessionid
            -rw-r--r--   1 root root 0 Jan 19 15:16 setgroups
            -r--r--r--   1 root root 0 Jan 19 15:16 smaps
            -r--r--r--   1 root root 0 Jan 19 15:16 smaps_rollup
            -r--------   1 root root 0 Jan 19 15:16 stack
            -r--r--r--   1 root root 0 Jan 19 15:01 stat
            -r--r--r--   1 root root 0 Jan 19 15:16 statm
            -r--r--r--   1 root root 0 Jan 19 15:02 status
            -r--------   1 root root 0 Jan 19 15:16 syscall
            dr-xr-xr-x   3 root root 0 Jan 19 15:16 task
            -r--r--r--   1 root root 0 Jan 19 15:16 timers
            -rw-rw-rw-   1 root root 0 Jan 19 15:16 timerslack_ns
            -rw-r--r--   1 root root 0 Jan 19 15:16 uid_map
            -r--r--r--   1 root root 0 Jan 19 15:16 wchan
          
里面的数据还挺多的,不过,比较有趣的其实是两个文件,分别是:cmdline:这个进程被启动的指令串;environ:这个进程的环境变量内容。
很有趣吧!如果你查阅一下cmdline的话,就会发现:
            [root@initroot ~]# cat /proc/1/cmdline
            /usr/lib/systemd/systemd--switched-root--system--deserialize22
          
就是这个指令、选项与参数启动 systemd进程 的啦!这还是跟某个特定的 PID 有关的内容呢,如果是针对整个 Linux 系统相关的参数呢? 那就是在 /proc 目录底下的文件啦!相关的文件与对应的内容是这样的: (注 3)
檔名
文件内容
/proc目录
linux文件类型
文件名 文件内容
/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 去查阅看看,不必深入了解, 不过,观看过文件
内容后,毕竟会比较有感觉啦!如果未来您想要自行撰写某些工具软件, 那么这个目录底下的相关
文件可能会对您有点帮助的喔!

1.fuser找出正在使用某个文件的进程

回到顶部

当你在删除某个文件时,这个文件却被某个进程占用着,这时候是不能删除的。那么怎么找到占用该文件的进程呢? 或者你用umount卸载某个文件系统,却出现了device is busy的提示,这表明文件系统正在被某个进程使用。 这时候就可以使用fuser命令了:

              [root@initroot ~]# fuser [-umv] [-k [i] [-signal]] file/dir
            
选项与参数:
-u :除了进程的PID之外,同时列出该进程的拥有者;
-m :该文件所在的文件系统,后面接的那个文件名会主动的上提到该文件系统的最顶层,对umount不成功很有效!
-v :可以列出每个文件与进程还有指令的完整相关性!
-k :向找到的进程发送信号,信号由-signal指定,如果没有指定信号名或者信号编号,默认为SIGKILL信号;
-i :用户交互模式,必须与-k配合,在删除进程之前会先询问使用者!
-signal:例如 -1 -15 等等,若不加的话,默认是 SIGKILL (-9) 啰!
找出目前所在目录的使用 PID/所属账号/权限 为何。 看看有哪些进程正在使用当前工作目录:
              [root@initroot ~]# fuser -uv .
                                  USER        PID ACCESS COMMAND
              /root:               root       6632 ..c.. (root)bash

              
正在使用当前工作目录的进程为bash进程,进程pid为6632,该进程属于root用户。比较有趣的是ACCESS字段,该字段代表的意义为:
c :此进程在当前的目录下(非次目录);
e :可被触发为执行状态;
f :是一个被开启的文件;
r :代表顶层目录(root directory);
F :该文件被开启了,不过在等待回应中;
m :可能为分享的动态函式库;
-m选项可以查看文件所在的文件系统中有多少进程正在占用该文件系统
找到所有使用/proc这个文件系统的进程吧!
              [root@initroot ~]# fuser -uv /proc
              USER        PID ACCESS COMMAND
              /proc:               root     kernel mount (root)/proc
              rtkit      1436 .rc.. (rtkit)rtkit-daemon
            
数据量还不会很多,虽然这个目录很繁忙~没关系!我们可以继续这样作,看看其他的进程!
              [root@initroot ~]# fuser -mvu /proc
              USER        PID ACCESS COMMAND
              /proc:               root     kernel mount (root)/proc
              root          1 f.... (root)systemd
              root        377 f.... (root)systemd-journal
              systemd-resolve    580 f.... (systemd-resolve)systemd-resolve
              syslog      708 f.... (syslog)rsyslogd
              root        727 f.... (root)udisksd
              root        964 F.... (root)Xorg
              peter      1174 f.... (peter)systemd
              peter      1428 f.... (peter)csd-housekeepin
              rtkit      1436 .rc.. (rtkit)rtkit-daemon
              peter      1474 f.... (peter)gvfs-udisks2-vo
              peter      1553 f.... (peter)nemo-desktop
              peter      1609 f.... (peter)gvfsd-trash
              peter      2180 .rc.. (peter)Web Content
              peter      2289 .rc.. (peter)WebExtensions
              peter      2383 .rc.. (peter)Web Content
              peter      3422 f.... (peter)nemo
              peter      3941 .rc.. (peter)Web Content
              peter      4371 f.... (peter)xreader
              peter      4387 f.... (peter)WebKitNetworkPr
              root       6620 f.... (root)systemd
            
有这几支进程在进行 /proc 文件系统的存取喔!这样清楚了吗?
范例三:找到所有使用到 /home 这个文件系统的进程吧!
先确认一下,自己的 bash PID 号码吧!
              [root@initroot ~]# echo $$
              31743
            
              [root@initroot ~]# cd /home
              [root@initroot home]# fuser -muv .
                        USER PID ACCESS COMMAND
              /home:    root kernel mount (root)/home
              peter 31535 ..c.. (peter)bash
              root 31571 ..c.. (root)passwd
              root 31737 ..c.. (root)sudo
              root 31743 ..c.. (root)bash
            
# 果然,自己的 PID 在啊!
              [root@initroot home]# cd ~
              [root@initroot ~]# 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@initroot ~]# fuser -mki /home
              /home:
              31535c 31571c 31737c
              # 你会发现, PID 跟上面查到的相同!
              Kill process 31535 ? (y/N) 
            
# 这里会问你要不要删除!当然不要乱删除啦!通通取消! 既然可以针对整个文件系统,那么能不能仅针对单一文件啊?当然可以啰!
看一下底下的案例先:
范例四:找到 /run 底下属于 FIFO 类型的文件,并且找出存取该文件的进程
              [root@initroot ~]# find /run -type p
              .....(前面省略).....
              /run/systemd/sessions/165.ref
              /run/systemd/sessions/1.ref/run/systemd/sessions/c1.ref
            
# 随便抓个项目!就是这个好了!来测试一下!
              [root@initroot ~]# 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 可以让我们了解到某个文件 (或文件系统) 目前正在被哪些进程所利用!

2.lsof列出进程所打开的文件名

回到顶部

fuser是通过文件名找出占用该文件或者文件系统的进程,而lsof命令则可以查看进程打开的文件或者使用的文件系统。

              [root@initroot ~]# lsof [-aUu] [+d]
            
选项与参数:
-a :多项数据需要同时成立才显示出结果时! -U :仅列出 Unix like 系统的 socket 文件类型; -u :后面接 username,列出该使用者相关进程所开启的文件; +d :后面接目录,亦即找出某个目录底下已经被开启的文件!
列出目前系统上面所有已经被开启的文件与装置:
              [root@initroot ~]# lsof
              lsof: WARNING: can't stat() fuse.gvfsd-fuse file system /run/user/1000/gvfs
                    Output information may be incomplete.
              COMMAND    PID  TID            USER   FD      TYPE             DEVICE  SIZE/OFF       NODE NAME
              systemd      1                 root  cwd       DIR                8,1      4096          2 /
              systemd      1                 root  rtd       DIR                8,1      4096          2 /
              systemd      1                 root  txt       REG                8,1   1595792    1049085 /lib/systemd/systemd
              systemd      1                 root  mem       REG                8,1   1700792    1053812 /lib/x86_64-linux-gnu/libm-2.27.so
              systemd      1                 root  mem       REG                8,1    121016    1049149 /lib/x86_64-linux-gnu/libudev.so.1.6.9
              systemd      1                 root  mem       REG                8,1     84032    1053790 /lib/x86_64-linux-gnu/libgpg-error.so.0.22.0
              systemd      1                 root  mem       REG                8,1     43304    1053801 /lib/x86_64-linux-gnu/libjson-c.so.3.0.1
              systemd      1                 root  mem       REG                8,1     34872     532281 /usr/lib/x86_64-linux-gnu/libargon2.so.0
              ...(省略)...
            
如果不加任何参数,lsof默认会将目前系统上面已经开启的文件全部列出来。可以看到目前系统中打开的文件非常多。可以注意到,第一个文件 systemd 执行的 地方就是根目录,而根目录所在的 inode 也有显示出来了!
仅列出关于 root 的所有进程开启的 socket 文件
              [root@initroot ~]# lsof -u root -a -U
              lsof: WARNING: can't stat() fuse.gvfsd-fuse file system /run/user/1000/gvfs
                    Output information may be incomplete.
              COMMAND    PID USER   FD   TYPE             DEVICE SIZE/OFF   NODE NAME
              systemd      1 root   14u  unix 0xffff8c980d33e400      0t0  14487 /run/systemd/notify type=DGRAM
              systemd      1 root   15u  unix 0xffff8c980d33e800      0t0  14488 type=DGRAM
              systemd      1 root   16u  unix 0xffff8c980d33f400      0t0  14489 type=DGRAM
              systemd      1 root   17u  unix 0xffff8c980d33e000      0t0  14490 /run/systemd/private type=STREAM
              systemd      1 root   18u  unix 0xffff8c980dc44400      0t0  24013 /run/systemd/journal/stdout type=STREAM
              systemd      1 root   19u  unix 0xffff8c980ddb3c00      0t0  24265 /run/systemd/journal/stdout type=STREAM
              systemd      1 root   20u  unix 0xffff8c981625c800      0t0  24329 /run/systemd/journal/stdout type=STREAM
              systemd      1 root   21u  unix 0xffff8c981625d800      0t0  24330 /run/systemd/journal/stdout type=STREAM
              systemd      1 root   23u  unix 0xffff8c981833b400      0t0  23801 /run/systemd/journal/stdout type=STREAM
              systemd      1 root   26u  unix 0xffff8c980d33f000      0t0  14502 /run/systemd/journal/stdout type=STREAM
              systemd      1 root   27u  unix 0xffff8c980d33fc00      0t0  14504 /run/systemd/journal/socket type=DGRAM
              systemd      1 root   32u  unix 0xffff8c980c8d3800      0t0  14543 /run/systemd/coredump type=SEQPACKET
              systemd      1 root   33u  unix 0xffff8c980c8d3c00      0t0  14545 /run/systemd/fsck.progress type=STREAM
              systemd      1 root   34u  unix 0xffff8c980c8d2000      0t0  14547 /run/udev/control type=SEQPACKET
              systemd      1 root   35u  unix 0xffff8c980c8d3400      0t0  14550 /run/systemd/journal/dev-log type=DGRAM
              systemd      1 root   37u  unix 0xffff8c980c8d2400      0t0  14559 /run/lvm/lvmpolld.socket type=STREAM
              systemd      1 root   38u  unix 0xffff8c980c8d2c00      0t0  14563 /run/systemd/journal/syslog type=DGRAM
              systemd      1 root   44u  unix 0xffff8c9816219000      0t0  14569 /run/lvm/lvmetad.socket type=STREAM
              systemd      1 root   46u  unix 0xffff8c980ddb2800      0t0  15354 type=DGRAM
              systemd      1 root   48u  unix 0xffff8c980dfbf800      0t0  16711 /run/systemd/journal/stdout type=STREAM
              ...(省略)...
            
注意到那个 -a 吧!如果你分别输入 lsof -u root 及 lsof -U ,会有啥信息?
使用 lsof -u root -U 及 lsof -u root -a -U ,呵呵!都不同啦!-a 的用途就是在解决同时需要两个项目都成立时啊! ^_^
列出目前系统上面所有的被启动的设备:
              [root@initroot ~]# lsof +d /dev
              lsof: WARNING: can't stat() fuse.gvfsd-fuse file system /run/user/1000/gvfs
                    Output information may be incomplete.
              COMMAND    PID            USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
              systemd      1            root    0u   CHR    1,3      0t0    6 /dev/null
              systemd      1            root    1u   CHR    1,3      0t0    6 /dev/null
              systemd      1            root    2u   CHR    1,3      0t0    6 /dev/null
              systemd      1            root    3w   CHR   1,11      0t0   12 /dev/kmsg
              systemd      1            root   24r   CHR 10,235      0t0  402 /dev/autofs
              systemd      1            root   70u   CHR  10,62      0t0    4 /dev/rfkill
              kdevtmpfs   15            root  cwd    DIR    0,6     4080    2 /dev
              kdevtmpfs   15            root  rtd    DIR    0,6     4080    2 /dev
              systemd-j  377            root    0r   CHR    1,3      0t0    6 /dev/null
              systemd-j  377            root    1w   CHR    1,3      0t0    6 /dev/null
              systemd-j  377            root    2w   CHR    1,3      0t0    6 /dev/null
              systemd-j  377            root    7w   CHR   1,11      0t0   12 /dev/kmsg
              systemd-j  377            root    9u   CHR   1,11      0t0   12 /dev/kmsg
              lvmetad    405            root    0r   CHR    1,3      0t0    6 /dev/null
              systemd-u  407            root    0r   CHR    1,3      0t0    6 /dev/null
              systemd-r  580 systemd-resolve    0r   CHR    1,3      0t0    6 /dev/null
              dbus-daem  586      messagebus    0u   CHR    1,3      0t0    6 /dev/null
            
# 看吧!因为装置都在 /dev 里面嘛!所以啰,使用搜寻目录即可啊!
秀出属于 root 的 bash 进程所开启的文件
              [root@initroot ~]# lsof -u root | grep bash
              lsof: WARNING: can't stat() fuse.gvfsd-fuse file system /run/user/1000/gvfs
                    Output information may be incomplete.
              bash      6632 root  cwd       DIR                8,1     4096    2621441 /root
              bash      6632 root  rtd       DIR                8,1     4096          2 /
              bash      6632 root  txt       REG                8,1  1113504    4456451 /bin/bash
              bash      6632 root  mem       REG                8,1    47568    1053839 /lib/x86_64-linux-gnu/libnss_files-2.27.so
              bash      6632 root  mem       REG                8,1    97176    1053833 /lib/x86_64-linux-gnu/libnsl-2.27.so
              bash      6632 root  mem       REG                8,1    47576    1053850 /lib/x86_64-linux-gnu/libnss_nis-2.27.so
              bash      6632 root  mem       REG                8,1    39744    1053835 /lib/x86_64-linux-gnu/libnss_compat-2.27.so
              bash      6632 root  mem       REG                8,1  4795856     531033 /usr/lib/locale/locale-archive
              bash      6632 root  mem       REG                8,1  2030544    1053749 /lib/x86_64-linux-gnu/libc-2.27.so
              bash      6632 root  mem       REG                8,1    14560    1053772 /lib/x86_64-linux-gnu/libdl-2.27.so
              bash      6632 root  mem       REG                8,1   170784    1053907 /lib/x86_64-linux-gnu/libtinfo.so.5.9
              bash      6632 root  mem       REG                8,1   170960    1053721 /lib/x86_64-linux-gnu/ld-2.27.so
              bash      6632 root  mem       REG                8,1    26376     790981 /usr/lib/x86_64-linux-gnu/gconv/gconv-modules.cache
              bash      6632 root    0u      CHR              136,0      0t0          3 /dev/pts/0
              bash      6632 root    1u      CHR              136,0      0t0          3 /dev/pts/0
              bash      6632 root    2u      CHR              136,0      0t0          3 /dev/pts/0
              bash      6632 root  255u      CHR              136,0      0t0          3 /dev/pts/0
            
这个指令可以找出您想要知道的某个进程是否有启用哪些信息!

七.与进程相关的其他命令

回到顶部

还有一些与进程有关的命令可以值得参考与应用

3.pidof通过进程名打印进程的PID

回到顶部

              [root@initroot ~]# pidof [-sx] program_name
            
选项与参数:
-s :仅列出一个PID而不列出所有的PID
-x :同时列出该program name可能的PPID那个进程的PID
列出目前系统上面systemd以及rsyslogd这两个进程的PID
              [root@initroot ~]# pidof systemd rsyslogd
              6620 1174 708
            
# 理论上,应该会有两个 PID 才对。上面的显示也是出现了两个 PID 喔。 # 分别是 systemd 及 rsyslogd 这两支程序的 PID 啦。
很简单的用法吧,透过这个 pidof 指令,并且配合 ps aux 与正规表示法,就可以很轻易的找到您所想要的进程内容了呢。 如果要找的是bash ,那就 pidof bash ,立刻列出一堆PID号码了~

initroot编辑整理,转载请注明www.initroot.com