值得收藏,史上最全Linux ps命令详解

您所在的位置:网站首页 linux中的ps 值得收藏,史上最全Linux ps命令详解

值得收藏,史上最全Linux ps命令详解

2023-02-20 17:21| 来源: 网络整理| 查看: 265

不过随着对linux ps命令使用的逐步深入,对ps命令的其他疑问越来越多。比如,我们天天在使用ps命令时输出的%CPU列到底是什么含义?为什么和top显示的%CPU的值有时候差异非常大?

再比如,当我使用ps -el命令时,为什么我的进程名是systemd-journald,而ps命令只显示systemd-journal,弄丢了最后1个字母d。

带着这么多疑惑,3年多前我有机会简单的学习了一下linux ps源代码,逐步解开了上面这些疑惑。后来发现公司的很多同事也对ps命令有各种问题和疑问,于是想把之前对ps命令的学习经验总结成文档,供大家参考。希望能给大家带来帮助。

二、Linux ps命令选项解析

Linux ps命令功能很强大,了解ps命令首先需要从ps命令的选项格式入手。像其他很多linux shell命令一样,ps命令的选项也有长格式和短格式的区别。短选项中也可以带中横线、也可以不带中横线。

根据选项长短和是否有横线的情况,ps命令的选项可以分为以下3类:

BSD风格语法,必须不能以中横线开头; SYSV风格语法,必须仅一个中横线开头; GNU风格语法,必须以两个中横线开头;

不过linux ps命令的长选项并不多,而且几乎每个长选项都有一个功能完全相同的短选项对应。在centos7环境运行如下命令可以见。

在本文中我们将主要介绍BSD和SYSV两种风格的ps命令选项。如果大家有对GNU风格的长选项使用的需求,那么可以参考对应的短选项语法即可。需要注意的是GNU风格选项都是带参数值的,例如—sid 1。

各风格的ps命令选项可以混合使用,比如:

Linux ps命令解析SYSV和BSD风格选项时,会分别将每组字符串都解析成单独的字母。以下三个实例,拆分前后的命令都是等价的。

从示例中可以看出,当SYSV风格语法一个中横线之后有多个字母选项时,拆分后需要给每一个字母前都加上一个中横线。也就是说-elL转换为-e -l -L,而不是转换为-e l L。

从上面例子中也可以看出,ps命令选项除了有是否加中横线的区别,字母大小写也表现为不同的选项含义。英文字母一共26个,SYSV风格选项-A到-Z和-a到-z共52个,BSD风格选项A到Z和a到z共52个。于是ps命令就有一共104个命令选项可能性。

不同版本的ps命令选项的使用可能略有出入,本文主要使用主流的centos7上的procps-ng version 3.3.10版本来说明。

在这104个命令选项中,未启用的或曾经使用过现在废弃的命令选项有如下40个,分别是A、B、C、D、E、F、G、I、J、K、P、Q、R、W、Y、b、d、i、y、z、-B、-D、-E、-I、-J、-K、-Q、-R、-S、-W、-X、-Y、-b、-h、-i、-k、-r、-v、-x和-z。

既然是未启用或已废弃,那么运行带这个选项的ps命令应该会报错。试运行下大部分确实如此,不过也有几个例外,比如ps -x命令就不报错,可以正常输出。这样的例外选项一共有如下7个-S、-X、-h、-k、-r、-v和-x,本文第九节会给予说明。

这104个命令选项中的其余64个选项就构成了linux ps命令的庞大命令选项体系,接下的内容就对他们分别给予介绍。

要查看我们当前ps命令的版本,就用到V、-V这2个选项。

为了本文中意思表达更加准确,这里借用数据库中的几个概念。ps命令输出结果,约定为结果集。结果集中的每一行,我们约定为记录(record)。结果集或记录中的每一列,我们约定为字段(field)。

三、Linux ps命令的记录类选项

差不多每一个工程师使用ps命令时应该都有这样的疑问, 使用ps aux时输出结果中记录行数要远大于只使用ps命令时(如下所示)。

这其实会让很多工程师在使用ps命令查找需要的进程时心里很忐忑,会不会由于命令的选项使用不当导致ps没有列出所需要的进程信息。正是这个原因,我们首先需要搞懂ps命令影响记录行数的那些选项。

3.1、all_processes选项

Linux ps命令的记录类选项大概有20几个之多。有些可以列出所有的进程信息,有些按某种规则筛选显示部分进程信息。如今操作系统中awk、sed和grep这些shell文本处理命令的功能都十分强大,我们重点还是掌握ps命令中那些显示所有进程信息记录的选项,其他ps命令过滤选项都可以通过shell文本处理命令(awk、sed和grep)间接实现。

Linux ps命令显示所有进程信息的选项只有2个,即SYSV风格的-e和-A。相比之下,-e更容易记忆和书写,请大家牢记这个-e选项。

大家知道,ps命令的所有信息都是linux kernel生成,并通过/proc/目录输出给用户空间的。在/proc/目录下,每一个以数字开头的目录,就对应一个进程信息。既然如此,通过如下命令便可一目了然。

参数-e和-A显示的进程记录数确实和proc目录下的所有进程目录数一致。

3.2、simple_select选项

Linux ps命令的simple_select选项一共5个,具体包括-a、-d、a、g和x。他们包括2个SYSV风格和3个BSD风格选项。2个SYSV风格和3个BSD风格的选项不能同时使用,否则会报错。

2个SYSV风格或3个BSD风格内部可以组合使用,具体的组合可能性有-ad、ga、ax、gx、agx。这里值得注意的是这种字母组合选项绝对不是单字母选项筛选规则的简单组合,ps命令给这几种组合赋予了新的筛选规则。

Linux环境下的ps命令,会对BSD风格simple_select选项部分做2个特殊处理:

在原来的BSD风格simple_select情况下,再额外增加一个g选项; 如果已经有a、g和x三个选项都出现了,那么就直接替换为-e选项;

按照这2个特殊处理规则,ps aux选项组合等价于ps auxg,等价于ps agx u,等价于ps -e u。

总结下来,ps命令simple_select选项只有6种组合情况-a、-d、-ad、g、ga、gx。每一种选项都赋予一个位图值。ps命令通过位图计算来实现它的筛选规则。比如g选项的位图值select_bits是0x0a0a,下面以g选项为例说明。

关于8、4、2、1的含义(关于tty、session、tgid和euid字段含义参考第七节):

“8” tty值等于当前进程tty值的进程; “4” tty值为空的进程; “2” session值等于当前进程tgid(pid)值的进程; “1” euid值等于当前进程euid值的进程;

很明显“4”这位都缺失,1这位都存在,那么g选项的含义就是:显示所有tty值存在的且euid值等于当前进程euid值的进程。对此持怀疑态度的同学可以通过如下2个命令进行验证。

同样的分析方法,其他几个选项和选项组合的含义:

选项-a含义:显示所有tty值存在的且session值不等于当前进程tgid(pid)值的进程; 选项-d含义:显示所有session值不等于当前进程tgid(pid)值的进程; 选项组合-ad含义:显示所有tty值存在的或session值不等于当前进程tgid(pid)值的进程。换句话说,被过滤掉的是所有tty值为空的且session值等于当前进程tgid(pid)值的进程; 选项组合ga(或选项a)含义:显示所有tty值存在的进程; 选项组合gx(或选项x)含义:显示所有euid值等于当前进程euid值的进程;

这类选项比较容易理解,都是根据进程的某个属性值对进程进行筛选。他们大多需要一个选项的参数,而且也都有功能完全一样的GNU风格的长选项对应。此类选项一共13个,主要分为如下几组:

进程ID选项,查询PID值为一个或几个PID值范围的进程信息。

进程会话(session)ID选项,有关SessionID可以参见8.1小节。

用户ID选项,参见8.7小节。

用户组ID选项,参见8.7小节。

进程名称选项,显示符合当前进程名称参数的进程。这里需要注意,当进程名参数值字符串长度大于15时,只是用其前15位作为匹配条件,参见8.2小节

进程终端(tty)选项

这些选项不但可以单独使用,还可以组合使用(如下所示)。需要注意的是这些选项之间的组合是逻辑或的关系,即或者符合-u选项条件或者符合-p选项条件。

$ ps -u root -p 1

3.4、特殊选择选项

当不希望结果中出现标题页头这一行信息时,h选项可以隐藏ps输出结果中的标题栏。

如果我们只希望列出运行中的R状态和D状态的进程,r 选项选中时将只显示其他筛选条件过滤后的结果集中的R和D状态进程。帮助手册上写只筛选R状态是不正确的,这里也包括D状态进程的筛选。 有时候如果我们需要显示的进程记录不好筛选,但是他的补集却很容易筛选。那我们可以使用-N选项。选中此选项时,将以系统中所有进程(ps -e结果)为全集对前述条件筛选后的结果取补集,即只显示原来不显示的记录。下面的例子中,去掉标题栏一行信息后,472等于456加16,说明全集等于本集加补集(如下示例所示)。

3.5、记录类选项的作用顺序

本节前几部分全面的介绍了记录筛选类选项,本小节将对这些选项的综合作用顺序进行一个系统介绍。

记录类选项是对/proc/目录下的进程信息逐条筛选过滤的:

首先判断是否有all_processes选项。如果有all_processes选项,则本条记录被选择。如果没有all_processes选项,则继续下一规则。 其次判断是否有simple_select选项。如果有simple_select选项,则使用simple_select选项规则判断本条记录是否被选中。如果没有被simple_select选项选择,则继续下一条规则。 然后判断是否有selection_list选项。如果有selection_list选项,则使用selection_list选项判断本条记录是否被选中。如果没有selection_list选项,则继续下一条规则。 然后判断选项中是否有BSD风格的选项。如果有BSD风格选项,则使用simple_select类的选项g规则判断本条记录是否被选中。如果没有BSD风格选项,则进入下一条规则。 此时不论ps命令有SYSV风格选项还是仅无选项ps命令,都会使用一个新的simple_select选项位图进行筛选过滤,位图值为0xaa00。如果还没有被选中,则彻底失去被选中的机会。位图值0xaa00的意义是:所有tty值等于当前进程tty的且euid值等于当前进程euid值的进程。 接下来再看是否有r选项。如果有r选项则以上5个环节被选中的记录中,只有R和D状态的记录才能被继续选中。如果没有r选项,则以上5个环节中被选中的记录,都继续被选中。 最后看是否有-N选项,如果有-N选项则以上第6个环节选中的将不被选中,第6个环节未选中的将被选中。如果没有-N选项,则以上第6个环节中被选中的记录,还继续被选中。 选项h单独生效,如果有h选项则取消结果集的标题栏,如果没有h选项则标题栏保持输出。

上面一章介绍了记录类选项的使用,了解了如何筛选符合我们要求的记录集。如果我们需要对输出结果进行排序,那么ps命令也给我们提供了3个选项,分别是k、f和-H。

4.1、字段排序选项

选项k可以让我们以某个字段为条件对输出结果进行排序,并且还可以使用+-符号设置升序排序还是降序排序。

选项k还可以使用多个字段同时对结果集排序,从输出结果可以看到,先按ppid进行升序排序,ppid值相同时,再按rss值进行升序排序。

4.2、树形排序选项

每一个进程都有一个父进程,所有用户空间的进程的最终父进程都是1号进程,所有内核空间的线程的最终父线程都是2号线程。这样所有进程按照父子进程的关系就可以构成2个树形结构。选项f和-H就是实现这个树形排序功能的2个选项。

从上面的结果中不难看出,选项f是使用ACSII码对父子进程进行关联,选项-H是使用tab空格对父子进程进行关联。

五、Linux ps命令线程展开选项

前面章节主要是说明了如何筛选和显示进程的信息。同一个进程有时候还会起多个线程,同样内核也在/proc/目录下显示了进程的线程信息,如下所示。

Linux ps同样提供了一组选项可以将每个进程的线程信息详细展现,这组选项包括H、-L、-T、M、m和-m。在讲解这些选项之前,我们先看一个小测试。

同样为了统计的准确,用h选项去掉标题栏信息。其中最后一个486的值是ps -e h的记录数,说明当前系统有486个进程。非常巧的是486恰巧等于1217减去731的值。从这里我们可以了解到H、-L和-T这3个选项记录数都是731,M、m和-m三个选项记录数都是1217。找一个起了多线程的进程查看下具体输出内容。

选项-L的输出可以看到一共4行输出结果,第一行PID等于LWP(线程ID)的值,说明是线程组的主线程(即进程)。其余三个线程ID各不相同,但PID值都和主线程的PID值一样,说明是同一线程组的普通线程。

第二组三个选项单纯的显示不便识别,我们这里先引入一个后面讲解的O选项,额外增加一个输出值LWP。

可以看到一共5行输出结果,对照上面的输出我们可以判断出,第二组选项除了把线程组中的4个线程分别显示之外,又额外增加了一行内容专门用于显示这个线程组(即进程)的信息。我们再回头看前面的1271减去731等于486应该就很容易明白了。

在H、-L和-T之间,以及M、m和-m之间,输出信息也略有不同,不过这些都是数据项和格式的不同,后面有专门章节介绍。

六、Linux ps命令的字段选项 6.1、字段组合类通用选项

很多人在使用ps命令时都会注意到,在我们输入不同的命令组合时,ps命令输出结果中列的数据项并不统一。比如下面2个命令。

Linux ps命令的aux选项组合输出PID、%CPU、%MEM、RSS、TIME等数据项,ps命令的-el选项组合输出PID、PPID、WCHAN、TIME、CMD等数据项。首先一个问题就是,ps命令一共有多少数据项可以输出。这个问题很好回答,通过L选项很容易获取,一共有168个数据输出项。

其次的一个问题就是,是什么决定了ps aux命令输出结果中恰恰包含USER、PID、%CPU、%MEM、VSZ、RSS、TTY、STAT、START、TIME和COMMAND这11个数据项呢。原因是ps命令中有一些选项用来对数据字段进行固定组合的作用。其中aux中的u选项就固定包含了以上11个数据输出项,并且他们的显示顺序也已经固化在代码中。

Linux ps命令这种字段组合类选项一共15个。其中6个选项用途比较广泛,其余9个选项都主要适合在查询某一种问题时使用。

本小节先介绍6个通用选项:

面向用户角度来显示进程状况,其中的%CPU、%MEM、VSZ和RSS字段都是非常常用的信息。

采用详细格式显示进程状况,此类选项所显示字段主要为一些常用字段信息。

采用完整格式显示进程状况,此类选项所显示字段同样为一些常用字段信息。

6.2、字段组合类专用选项

本小节先介绍9个适合特殊用途的专用选项:

采用作业(job)控制的格式显示进程状况,字段PPID、PID、PGID、SID和TPGID都是此选项的关键信息。

采用旧式的linux i386寄存器格式显示进程状况,很明显此选项特点是STACKP、ESP和EIP这些寄存器信息。

Linux或sunos操作系统中会额外增加PSR字段的显示,PSR字段是指当前进程被调度到的CPU核序号。

采用程序信号的格式显示进程状况,此选项特色字段是PENDING、BLOCKED、IGNORED和CAUGHT字段。很显然,当我们进行linux信号编程时,使用此选项非常有用。

采用虚拟内存的角度显示进程状况,此选项特色字段包括MAJFL、TRS、DRS、RSS和%MEM。

打印操作系统强制访问控制(SELinux)的安全标签信息,此选项特点是LABEL字段信息。

也许有人已经观察到了,以上字段组合选项,不论哪个都会固定的有几个字段总是出现,比如PID、TTY、TIME和CMD等。下面请大家先看一下这几个例子。

从以上例子中,我们可以得出几个信息。参数为BSD风格时,默认都会显示PID、TTY、STAT、TIME和COMMAND这5个字段。参数为SYSV风格时,默认都会显示PID、TTY、TIME和CMD这4个字段。ps命令无参数时默认为SYSV风格。

6.3、自定义字段选项

上一小节字段组合选项是ps命令为了一些常用场景固化在代码中的固定数据项组合。但是如果以上所有组合都不满足我们的要求,或者我们为了提升ps命令运行效率仅仅需要个别的数据项输出。那么我们可以通过-o或o选项来实现自定义数据项的输出功能。比如我们对ps j这个命令字段组合的输出信息不满意,我们自定义他的输出。

前文提到过,ps命令一共可以输出168个字段,ps L命令可以显示这168个字段的详细情况。第一列小写字母是-o选项的参数,可以通过逗号隔开。第二列大写字母是ps命令输出的结果集标题栏名称。

尽管大部分情况下-o参数和标题栏都仅仅是大小写的转换关系,但也有不那么完美的时候,以进程的执行命令字段为例。

这个例子至少可以说明两点,不同的说明符(specifier,-o选项参数)可能输出同样的标题栏。尽管标题栏一样,但显示的内容可能是有区别的。

有些说明符还提供缩写,下表是ps命令有缩写的说明符和缩写的对应关系表,一共15个。

有了说明符的缩写之后,可以对自定义字段的输出字段之间添加自定义分隔符。区别于以往ps命令各输出字段都是使用空格作为分割,使用自定义分隔符之后将更方便使用shell数据处理命令进行解析。

前文提到所有字段组合选项都默认包含4个或5字段。如果想在自定义字段组合时也默认添加一些常用字段,而同时又省去-o选项参数的输入过程,那么可以使用O或-O选项。

这2个选项O或-O,会在自定义字段之前默认增加pid字段,在自定义字段之后默认增加state、tname、time和command字段。

七、Linux ps命令字段修饰选项

本节前面的选项都是决定输出结果中字段的数量和顺序,本小节将介绍几个只对输出结果中某个字段进行修饰的选项。首先来看-w和w选项。

这个实例说明,当屏幕不是很宽时,如果进程命令很长,默认情况下,会将命令超出屏幕的部分截取掉,这样势必会影响系统管理员调查问题,使用w或-w选项,就会将完整的进程命令信息显示,多出的部分换行显示。有的时候为了效果好一点,建议我们可以多使用几次w选项,比如ww、www或wwww。

接下来我们再来看一下c和e选项。

选项u的COMMAND字段,默认会输出进程路径和执行参数信息。从上面的例子可以看出,选项c可以使选项u的COMMAND字段更加精简,只保留进程名称。选项e可以使选项u的COMMAND字段更加丰富,增加进程环境变量的相关内容。

当选项S被选中,ps命令在显示如下6个字段信息时,会将已经死亡的子进程信息也包含计算在内,如果未选中S选项将不会计算这些已经死亡的子进程信息 。快速同时执行如下2个命令,即可看出这6个字段值,选中S值后比之前有明显增大。具体字段含义请参考8.5小节和8.6小节。

Linux ps命令的字段中有个wchan字段(wchan相关含义参考8.8小节)。默认情况下ps命令会输出wchan的符号信息,如果希望输出wchan的原始数值信息,可以使用n选项。请比较如下2个命令,添加n选项前后第11个字段的输出差别。除了wchan之外,选项n还可以将原本输出user name的地方转换为user id输出。

字段wchan的数值信息和符号信息的映射关系通过操作系统中一些System.map文件完成,如果用户需要使用自定义的System.map文件,可以通过选项N或-n完成,如下示例。

八、Linux ps命令常用字段

前文提到linux ps一共最多可以输出168个字段,通过ps L命令可获取详情。通过字段相关选项可以获取符合用途的字段组合。为了让大家对ps命令的理解更加深入,本节会深入介绍一些常用的输出字段的含义。

按照这些常用字段的内在关系,我们将分为以下八个小结介绍。

8.1、进程ID类字段

进程ID类字段是ps命令字段中最基础的一类。为了能更加形象的说明这些ID的关系和含义,请大家按照如下命令顺序操作。

对以上输出结果的字段逐条说明:

字段tid表示进程的线程ID,可以看出每个线程的tid都不相同。 字段nlwp表示当前线程组中的线程个数,以上命令都是单线程进程,因此此值均为1。 字段pid表示进程ID,也可以看出每个进程的PID都不相同。 字段pgid表示进程组ID,上面的例子中除了和setsid结合的vmstat命令,其余三组通过shell管道连接起来的命令的pgid都相同。比如tail、awk和nl命令的- pgid都为1384,且pgid值为组内第一个命令tail的pid值;iostat、sed和fold命令的pgid都为1388,且pgid值为组内第一个命令iostat的pid值。 字段sid表示会话ID。上面的例子中最后一行是第三个登录终端的shell。第一个登录终端上的所有进程sid都相同,且为登录shell的pid值1351;除了和set- sid结合的vmstat命令,第二个终端上的所有进程sid都相同,且为登录shell的pid值1394。 字段tpgid表示进程连接到的tty(终端)所在的前台进程组的ID。除了vmstat进程之外,第二个终端上的所有进程tpgid也都等于登录shell的pid值1394。但是第一个终端上的所有进程tpgid却都等于第一个终端上又启动的那个shell的进程id值1370。充分说明了tpgid值是链接着终端的前台进程组ID值。 字段ppid表示父进程ID。 最后我们再来解释和vmstat结合的setsid,setsid就是使和它结合的vmstat脱离原来的会话,脱离之后pgid和sid都等于了vmstat进程的pid,同时父进程也由1号进程托管。此时也没有了所依附的终端,tpgid统一等于-1。Linux上的所有守护进程的tpgid值都是-1。

进程ID类字段的别名情况:字段spid和字段lwp是字段tid的别名,字段tgid是字段pid的别名,字段pgrp是字段pgid的别名,字段sess和字段session是字段sid的别名。

8.2、命令名字段

命令名相关的字段一共有3组,如下所示。

命令名字段的别名情况:字段comm和字段ucomm是字段ucmd的别名,字段args和字段command是字段cmd的别名。

建议大家掌握ucmd和cmd这2个字段,cmd为长命令名字段,ucmd为短命令名字段,可以理解为unadorned cmd(未加修饰的命令名)。

前文提到过如果程序名称长度超过15位,ps命令的短命令名无法完整显示16位及以上的部分。下面看一个小例子来说明这个问题。

从上面的例子可以看出,当程序名称超过15位时,确实短命令名无法显示完整的程序名称,只显示了15位。进一步查看/proc/8040/目录,可以发现如下信息。

查询内核代码,可以发现comm值取自内核struct task_struct结构体的comm属性字段。

这就告诉我们通过ps命令短命令字段无论如何都无法输入超过15位的程序名称,原因是内核数据结构原生就只支持15个字符长度的程序名称。

除此之外上面的例子还给我们另外一个启示,如果通过使用SYSV风格的短命令名就可以满足使用要求(如ps -el),那就尽量不要使用BSD风格的长命令名(如ps -e u,即ps aux)。长命令名需要依赖内核中健康的文件系统,而当文件系统工作不正常时,往往短命令名却可以不受影响。所以我们在实际生产中偶尔会发现系统中有大量ps aux进程D住的情况。

8.3、进程状态字段

进程状态类字段一共有三个,分别是s、state和stat,如下所示。

字段s和state互为别名,值为单字节进程状态。这里重点介绍一下stat选项的多字节进程状态,查看一下ps命令关于这个多字节进程状态的c语言代码。

根据以上源代码,我们来逐条解释:

字符’


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3