原文连接:blog.csdn.net/juS3Ve/arti…linux
大概在十多年前,我当时仍是一个产品经理。因为一些工做的缘由,须要向运维工程师学习一些 linux 经常使用命令。当使用 linux ps 这个十分经常使用的命令时,遇到了一个小小的疑惑。有些工程师推荐使用 ps aux 的命令组合,有些工程师推荐使用 ps -aux 的命令组合,从输出结果上来看彷佛也没有什么不一样。考虑到如经常使用的 ls -l 命令在内,不少 linux 命令选项前都要加上一个短横线,这么来看彷佛 ps -axu 是正确的。可是一些早期的 linux 版本,在执行 ps -axu 时又会报出以下错误 Warning: bad syntax,而 ps aux 却没有这样的报错信息,这么看来彷佛 ps aux 又是正确的。查阅市面上的一些 linux 书籍,在介绍 linux ps 命令示例时,有些说用 ps aux,而有些又说用 ps -axu。实在是让我这个初学者摸不着头脑。ios
再后来,随着我加入运维团队对 linux ps 命令逐步深刻使用,学会了查看 man page 和 help,发现其中有 ps 命令的 exmaple,果真是 ps aux 的用法是正确的。不过随着对 linux ps 命令使用的逐步深刻,对 ps 命令的其余疑问愈来愈多。好比,咱们每天在使用 ps 命令时输出的 %CPU 列究竟是什么含义?为何和 top 显示的 %CPU 的值有时候差别很是大?再好比,当我使用 ps -el 命令时,为何个人进程名是 systemd-journald,而 ps 命令只显示 systemd-journal,弄丢了最后 1 个字母 d。程序员
带着这么多疑惑,3 年多前我有机会简单的学习了一下 linux ps 源代码,逐步解开了上面这些疑惑。后来发现公司的不少同事也对 ps 命令有各类问题和疑问,因而想把以前对 ps 命令的学习经验总结成文档,供你们参考。但愿能给你们带来帮助。算法
Linux ps 命令功能很强大,了解 ps 命令首先须要从 ps 命令的选项格式入手。像其余不少 linux shell 命令同样,ps 命令的选项也有长格式和短格式的区别。短选项中也能够带中横线、也能够不带中横线。shell
根据选项长短和是否有横线的状况,ps 命令的选项能够分为如下 3 类:数据库
BSD 风格语法,必须不能以中横线开头;编程
SYSV 风格语法,必须仅一个中横线开头;centos
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)。
差很少每个工程师使用 ps 命令时应该都有这样的疑问, 使用 ps aux 时输出结果中记录行数要远大于只使用 ps 命令时(以下所示)。这其实会让不少工程师在使用 ps 命令查找须要的进程时内心很忐忑,会不会因为命令的选项使用不当致使 ps 没有列出所须要的进程信息。正是这个缘由,咱们首先须要搞懂 ps 命令影响记录行数的那些选项。
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 目录下的全部进程目录数一致。
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 选项为例说明。
关于 八、四、二、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 个,主要分为以下几组:
这些选项不但能够单独使用,还能够组合使用(以下所示)。须要注意的是这些选项之间的组合是逻辑或的关系,即或者符合 - u 选项条件或者符合 - p 选项条件。
本节前几部分全面的介绍了记录筛选类选项,本小节将对这些选项的综合做用顺序进行一个系统介绍。
记录类选项是对 / 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。
选项 k 可让咱们以某个字段为条件对输出结果进行排序,而且还可使用 +- 符号设置升序排序仍是降序排序。
选项 k 还可使用多个字段同时对结果集排序,从输出结果能够看到,先按 ppid 进行升序排序,ppid 值相同时,再按 rss 值进行升序排序。
每个进程都有一个父进程,全部用户空间的进程的最终父进程都是 1 号进程,全部内核空间的线程的最终父线程都是 2 号线程。这样全部进程按照父子进程的关系就能够构成 2 个树形结构。选项 f 和 - H 就是实现这个树形排序功能的 2 个选项。
从上面的结果中不难看出,选项 f 是使用 ACSII 码对父子进程进行关联,选项 - H 是使用 tab 空格对父子进程进行关联。
前面章节主要是说明了如何筛选和显示进程的信息。同一个进程有时候还会起多个线程,一样内核也在 / 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 之间,输出信息也略有不一样,不过这些都是数据项和格式的不一样,后面有专门章节介绍。
不少人在使用 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 个通用选项:
本小节先介绍 9 个适合特殊用途的专用选项:
也许有人已经观察到了,以上字段组合选项,不论哪一个都会固定的有几个字段老是出现,好比 PID、TTY、TIME 和 CMD 等。下面请你们先看一下这几个例子。
从以上例子中,咱们能够得出几个信息。参数为 BSD 风格时,默认都会显示 PID、TTY、STAT、TIME 和 COMMAND 这 5 个字段。参数为 SYSV 风格时,默认都会显示 PID、TTY、TIME 和 CMD 这 4 个字段。ps 命令无参数时默认为 SYSV 风格。
上一小节字段组合选项是 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 字段。
本节前面的选项都是决定输出结果中字段的数量和顺序,本小节将介绍几个只对输出结果中某个字段进行修饰的选项。首先来看 - 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 一共最多能够输出 168 个字段,经过 ps L 命令可获取详情。经过字段相关选项能够获取符合用途的字段组合。为了让你们对 ps 命令的理解更加深刻,本节会深刻介绍一些经常使用的输出字段的含义。
按照这些经常使用字段的内在关系,咱们将分为如下八个小结介绍。
进程 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;除了和 setsid 结合的 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 的别名。
命令名相关的字段一共有 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 住的状况。
进程状态类字段一共有三个,分别是 s、state 和 stat,以下所示。
字段 s 和 state 互为别名,值为单字节进程状态。这里重点介绍一下 stat 选项的多字节进程状态,查看一下 ps 命令关于这个多字节进程状态的 c 语言代码。
根据以上源代码,咱们来逐条解释:
字符'<'表示 nice 值小于 0,nice 值最小为 - 20。进程特性 nice 值容许进程间接的影响内核调度算法。所谓 nice 就是指对其余进程的谦让程度,显然比 0 越小就越不谦让,比 0 越大就越谦让。顾名思义,越谦让的君子在 CPU 调度过程当中占用 CPU 的时间会越少,反之不谦让的进程相比较可能占用更多的 CPU 时间。所以字符'<'表示此进程可能在调度过程当中得到优点。
字符'N'表示 nice 值大于 0,nice 值最大为 19。所以字符'N'表示此进程可能在调度过程当中不能得到优点。
字符'L'表示进程 vm_lock 值为真,即此进程有内存页被锁在内存中,这些内存页不能经过换页换出。
字符's'表示进程的 tgid(pid) 值等于进程的 session(sid) 值,这说明当前进程是会话的 leader,参考 8.1 小节。
字符'l'表示进程中的线程数量大于 1,这说明当前进程是一个多线程程序。
字符'+'表示进程的 pgrp(pgid) 值等于进程的 tpgid 前台进程组 ID,这表示当前进程在前台进程组中。
时钟时间(系统时间)类字段,记录了进程开始时间点和执行的时长信息,这类字段一共有 6 组。其中 4 个记录进程开始时间点,2 个记录进程执行时长信息,示例以下。
从自动化运维脚本的角度,lstart 字段的输出信息格式更加规范便于解析,etimes 字段做为一个正整数也能够直接使用。字段 start_time 是字段 stime 的别名。下面给一个使用的例子。
字段 lstart 的输出固定占用了 2 2 6 这 5 列信息,这样在其后的 etimes 字段也固定占用了第 $7 列。使用 awk 结合 date 命令很方便的就将进程开始时间转化为时间戳格式。
CPU 时间和使用率类字段一共有 5 组,记录了进程所消耗的 CPU 时间片和 CPU 使用率信息,示例以下。
字段 bsdtime 的输出相比较 cputime 更加方便转换为正整数的秒数。字段 cp 的单位是千分比,不能超过 999。字段 c 是百分比,不能超过 99。
进程 CPU 时间类字段别名:字段 atime 和字段 time 是字段 cputime 的别名;字段 util 是字段 c 的别名;字段 %cpu 是字段 pcpu 的别名,可是 % 字符在 crontab 中使用并不友好,推荐使用 pcpu。
下面来讲明一下 ps 命令的 CPU 利用率的含义,先运行一个例子。
从这个命令运行的结果能够看出 bsdtime 除以 etimes 的值转换为百分比后,基本和 pcpu 的值相等。这就足以说明 ps 命令的 CPU 利用率字段指标是指从进程开始运行以来进程所耗费的 CPU 时间片占时钟时间的百分比。有时候这个值大于 100%,那是由于进程启用了多线程,不少时候有多核在同时使用 CPU 时间片。
看过 top 命令源码能够知道,top 命令默认是取最近 3 秒钟进程所耗费的 CPU 时间片除以 3 秒钟的百分比值。咱们能够设想一种场景,若是一个进程已经运行了 1 年以上,平时都很稳定。可是刚刚就在十几分钟前忽然运行大量线程,占用大量 CPU 资源。结果你在你刚刚登录系统以前 10 秒钟这些运行的线程都结束了。那么你不管是经过 top 命令的 CPU 利用率指标,仍是 ps 命令的 CPU 利用率指标都没法发现刚才做怪的这个线程的迹象。
进程内存相关字段也 ps 命令字段中很是重要的一类,主要分为以下 9 组,示例以下。
对以上输出结果的字段逐条说明:
字段 vsz(virtual memory size)表示进程所申请的虚拟地址空间的内存大小,单位 KB。在 64 位系统中,每一个进程都有 128Tb 大小的堆内存虚拟地址空间的内存空间大小。vsz 值并不反映进程占用的真正物理内存大小。
字段 rss(resident set size)表示进程真正占用了的物理内存大小,单位 KB。
字段 pmem 表示进程占用的物理内存大小 (rss) 占本机总物理内存大小百分比。
字段 trs(text resident set size)表示用于可执行代码的物理内存大小,约等于进程的程序尺寸大小。
字段 drs(data resident set size)表示可执行代码以外的内存大小,实际基本等于 vsz 减去 trs 的值。
字段 size 表示若是进程交换到磁盘所需的交换空间大小。
字段 sz 表示进程在物理页面中的核心镜像的大小。
字段 minflt 表示此进程中发生的次缺页异常的数量,下面详细介绍。
字段 majflt 表示此进程中发生的主缺页异常的数量。
进程内存相关字段别名:字段 m_drs 和字段 dsiz 是字段 drs 的别名,字段 vsize 是字段 vsz 的别名,字段 m_size 是字段 sz 的别名,字段 rssize、字段 rsz 和字段 sgi_rss 是字段 rss 的别名,字段 m_trs、字段 trss 和字段 tsiz 是字段 trs 的别名,字段 %mem 是字段 pmem 的别名,字段 min_flt 是字段 minflt 的别名,字段 maj_flt 和字段 pagein 是字段 majflt 的别名。
下面经过一个例子来加深对缺页异常的理解。
能够看出字段 rss 和字段 minflt 的比值趋近于 4。操做系统管理内存的基本单元是 4096 字节大小的页框,当进程访问还没有有物理内存创建页表映射关系的虚拟内存地址值时,会产生一次缺页异常。在缺页异常处理过程当中会为虚拟内存页分配一个物理内存页并创建映射。因此每一次缺页异常就会分配 4096(4kb)字节的物理内存,这样 rss 和 minflt 的比值固然就是 4 了。若是分配以后又有释放,后面再次分配,会使这个比值逐步小于 4。若是这个比值过于小,那咱们就有充足理由怀疑用户程序代码在内存管理上存在重大问题。
进程凭证类字段一共有 30 多个,其中大部分能够汇总为以下表格。
其中有些凭证是另外凭证的别名,好比 uid 是 euid 的别名,svuid 是 suid 的别名,fsuid 是 fuid 的别名。所以这些凭证字段简单的能够概括为以下 4 方面凭证:
实际凭证 (real user ID):通常表示进程的建立者,属于哪一个用户建立。
有效凭证 (effective user ID):表示进程对于文件和资源的访问权限,具有等同于哪一个用户的权限。
保护凭证 (saved set-user-ID):set-user-ID 的保存 ID。
文件系统凭证 (file-system user ID):已经基本废弃。
WCHAN 类字段一共 3 个 nwchan、wchan 和 wname。WCHAN 就是 waiting channel 的意思,进程正在休眠的内核函数的函数符号名称。R 状态进程此字段值为 “-”。
字段 wchan 和 wname 都显示的是内核函数的函数符号名称信息,默认只显示 6 个字节。若是但愿显示完整的函数名称,能够经过在字段名称后加冒号再加宽度数值的方式显示更丰富信息,即 wchan:25。
字段 nwchan 显示的是内核函数符号的指针地址数值信息。一个完整的 64 位的内核函数指针地址是一个 16 位的十六进制值,前 10 位固定为'ffffffff81',所以 ps 命令的 nwchan 字段只显示出了后 6 位的十六进制值。好比指针地址是 ffffffff8124bb7e,那么 nwchan 显示 24bb7e。若是后 6 位的高位有 0,则省略掉 0 的显示。
Linux ps 命令全部的选项和大多数字段都解释过了,如今该说说文章开头那个报错的 ps -axu 了。
ps 命令会提供一种选项容错机制。当用户输入的是一个 SYSV 风格参数组合后,若是参数解析失败,ps 命令会继续尝试把一样的字母组合都转换为 BSD 风格再尝试进行一次解析。好比 ps -aux 解析失败后尝试按 ps aux 解析,ps -x 解析失败后尝试按 ps x 解析。固然了,若是再次按照 BSD 风格尝试解析仍失败,那 ps 命令会最终失败报错。
事实上,能有机会被 ps 命令容错机制纠正的错误选项只有这 7 个,-S、-X、-h、-k、-v、-r 和 - x。由于这些字母虽然没有 SYSV 风格的选项,可是却都有 BSD 风格的选项。
最后说一下,没有将 BSD 风格到 SYSV 风格的容错机制,好比 SYSV 风格有 - F 选项,而 BSD 风格没有 F 选项。运行命令 ps F 仍是会报错。
本文对 linux ps 命令的 104 个短选项都进行了说明,其中只有一部分选项比较经常使用,下面根据个人经验推荐给你们重点关注:
选项 - e:显示全部进程的记录,记住这个参数就能够保证把当前系统的全部进程都输出。须要筛选进程时,能够结合 grep 等文本处理命令实现目的。
选项 h:选中时能够隐藏输出结果的标题栏信息,在一些自动化脚本中使用此参数能够去除页头信息。
选项 k:经过此选项能够实现对输出结果的排序。
选项 - L:经过此选项能够把多线程的进程展开每一个线程的细颗粒度。
选项 - l:或选项 l,此选项能够列出进程的最基本信息,包括 s、pid、ppid、time 和 ucmd 等字段信息。
选项 u:此选项能够列出 cpu 使用率、mem 使用率、rss 内存等字段信息。
选项 - o:或选项 o,经过此选项能够自定义输出符合本身需求的字段信息。
Linux ps 命令的 168 个输出字段,咱们也对大部分进行了介绍。下面根据经验推荐给你们一些经常使用的关注。