文章目录
ps
报告当前进程的快照
格式
ps [options]
描述
ps展示选择的活跃进程的信息。如果想要选择的进程的反复更新并显示,使用top(1)命令。
这个版本的ps接受若干种不同类型的选项:
- UNIX选项 可分组,并且必须有一个前置的横线
- BSD选项 可分组,并且一定没有前置横线
- GNU长选项 前面一定有两根前置横线
不同种类的选项可能会自由混合,但是可能会冲突。由于这个ps兼容的许多标准和ps实现,有一些在功能上相同的同义选项。
注意:ps -aux
区别于 ps aux
。POSIX和UNIX标准要求 ps -aux
打印所有由用户名为x的用户所拥有的所有进程,以及由-a选项选择的所有进程。如果名为x的用户不存在,这个ps将命令理解为 ps aux
并输出一个警告。这个行为主要是用来辅助老的脚本和习惯的迁移。这种机制是脆弱且可能会变化,因此不应该依赖于这种机制。
默认情况下,ps用相同的有效用户ID(euid=EUID)作为当前的用户来选择所有的进程,并且关联相同的终端作为调用者。ps展示进程ID(pid=PID),这个进程关联到的终端(tname=TTY),格式为[DD-]hh:mm:ss
的累积CPU时间(time=TIME),以及可执行文件的名字(ucmd=CMD)。输出默认是不排序的。
使用BSD风格的选项(没有前置线且可分组的选项)将在默认的显示中增加进程状态(stat=STAT)并展示命令的参数(args=COMMAND)而不是可执行文件的名字。你可以用PS_FORMAT这个环境变量来改变这些行为。使用BSD风格的选项也会改变进程选择的范围,会包含你(必须属于你这个用户的)拥有的其他所有终端上的(必须有终端)进程,这个行为也被描述为是在将选择的进程集合设置为过滤掉其他用户拥有的或者属于你自己但是不在终端上的进程。当这些选项的作用被描述为与下面的相同时,不考虑这些效果,因此将-M视为与Z相同,以此类推。
除了下面描述的这些之外,进程选择是附加的。也就是说默认选择的进程会被丢弃,选中的进程会被增加到待显示的集合中。如果一个进程满足任何选择的标准的话,这个进程将被展示出来。
实例
- 使用标准语法查看系统上的每个进程
ps -e
ps -ef
ps -eF
ps -ely
- 使用BSD语法查看系统上的每个进程
ps ax
ps aux
- 打印进程树
ps -ejH
ps axjf
- 获取关于线程的信息
ps -eLf
ps axms
- 获取安全信息
ps -eo euser,ruser,suser,fuser,f,comm,label
ps axZ
ps -eM
- 用用户的格式查看以root用户(实际的有效用户ID)运行的每个进程,
ps -U root -u root u
- 用用户定义的格式查看每个进程
ps -eo pid,tid,class,rtprio,ni,pri,psr,pcpu,stat,wchan:14,comm
ps axo stat,euid,ruid,tty,tpgid,sess,pgrp,ppid,pid,pcpu,comm
ps -Ao pid,tt,user,fname,tmout,f,wchan
- 仅仅打印syslogd的进程ID
ps -C syslogd -o pid=
- 仅仅打印PID42的名字
ps -q 42 -o comm=
简单的进程选择
- a (BSD风格)提升BSD风格的 "only yourself"限制(前面说了,BSD风格的仅仅选择自己用户拥有的所有终端上的进程)。这个"only yourself"的限制是当使用了BSD风格的选项(也就是没有前缀-)或者个人的设置是类BSD风格的时候,强加在所有进程的集合上的。这种方式选择的进程的集合会被附加到其他方式选择的进程集合上去。或者说,这个选项让ps列出所有有终端(tty)的进程,或者加上x选项时可以列出所有进程。
- -A (UNIX风格) 选择所有的进程,跟-e相同
- -a (UNIX风格) 选择除了会话老大和没有终端的进程之外的所有进程
- -d (UNIX风格) 选择除了会话老大之外的所有进程
- –deselect (GNU风格) 除了满足指定条件之外的所有进程,也就是反选,跟-N完全相同
- -e (UNIX风格) 选择所有的进程,跟-A相同
- g (BSD风格) 所有进程,即使是会话老大进程。已经过时了。
- -N (UNIX风格) 反选,完全同–deselect
- T (BSD风格) 所有跟这个终端关联的进程。完全等同于不带任何参数的t选项。
- r (BSD风格) 限制选择条件到仅仅正在运行的
- x (BSD风格) 提升BSD风格的"must have a tty"限制。这个"must have a tty"的限制是当使用了BSD风格的选项(也就是没有前缀-)或者个人的设置是类BSD风格的时候,强加在所有进程的集合上的。这种方式选择的进程的集合会被附加到其他方式选择的进程集合上去。或者说,这个选项让ps列出你所有拥有的全部进程(和ps拥有相同的EUID),或者加上a选项累出所有进程。
通过列表方式的进程选择
这些选项接受空格分隔或者是逗号分隔形式的单个参数。可以使用多次。例如ps -p "1 2" -p 3,4
- -123 等同于
--pid 123
- 123 等同于
--pid 123
- -C cmdlist
- 通过命令名来选择。这个选择出可执行文件名在cmdlist中的进程。
- 注意-C是大写C
- -G grplist
- 通过真实组ID(RGID)或者真实组名称来选择。这个选择出那些真实进程组的名字或者真实进程组的ID在grplist这个列表中的进程。
- 真实组ID标识创建进程的用户的组。参考getgid(2)
- -g grplist
- 通过session或者有效组名字来选。
- 通过session来选是被很多标准都指定的,但是通过有效组来选只是部分操作系统使用的逻辑行为。
- 当grplist是完全数字组成的时候,ps将通过session来选择。
- 仅仅当组名字也指定的时候,才会按照组ID号码来选。
- –Group grplist
- 通过实际组ID(RGID)或者名字来选,完全同于-G
- –group grplist
- 通过有效组ID或者名字来选。
- 这个选择出那些有效组名字或者ID在grplist中的进程
- 有效组ID描述的是进程使用的文件访问的权限的那个组。
- -g选项通常是–group的候选项。
- p pidlist
- -p pidlist
- –pid pidlist
- 通过进程ID来选择,p和-p和–pid等同
- –ppid pidlist
- 通过父进程的ID来选。选出来的是pidlist中列出的进程的子进程
- q pidlist
- -q pidlist
- –quick-pid pidlist
- 通过进程ID来选,快速模式,q 等同于-q 等同于 --quick-pid
- -s sesslist
- –sid sesslist
- 通过session id来选
- t ttylist
- 通过终端来选择,不同的是t可以后跟一个空的ttylist,此时跟T相同,仅啰嗦一点。
- -t ttylist
- 通过终端选择。
- 当ttylist为-时,选择所有不跟任何终端关联的进程。
- –tty ttylist
- 通过终端来选择,不同的是t可以后跟一个空的ttylist,此时跟T相同,仅啰嗦一点。
- U userlist
- 通过有效用户ID(EUID)或者名字来选。EUID描述的是这个进程用的哪个用户的文件访问权限。等同于-u和–user。
- -U userlist
- 通过实际用户ID(RUID)或者名字来选。RUID描述的是谁创建了这个进程。 等同于–User userlist
- -u userlist
- –User userlist
- 通过实际用户ID(RUID)或者名字来选。
- –user userlist
输出格式控制
这些选项用于选择ps显示的信息
- l 展示BSD长格式
- -l 长格式 -y选项通常跟这个一起使用
- -y 不展示flags,用rss来替换掉addr。这个选项仅仅可以用于-l一起使用。
- -c 展示-l选项的不同调度程序信息。
- –context 展示安全信息格式(for SELinux)
- -f 完整格式
- 这个选项可以组合很多其他的UNIX风格的选项来增加附加列。
- 也会引起命令行参数被打印
- 当使用-L选项,会增加NLWP(线程数量)和LWP(线程ID)列
- 参考c选项中的args和comm关键字
- -F 额外的完整格式 参考-f选项中的-F指定的。
- O format
* - -O format
- 正如-o,但是会预先加载一些默认列。
- 等同于-o pid,$format,state,tname,time,command
- 或者等同于 -o pid,$format,tname,time,cmd
- -o format
- 用户自己定格式
- format是一个用空格或者逗号分隔的列表形式的单个参数
- format提供一种机制来定制化输出列
- 关键字在下面的标准格式说明小节中。
- 表头可以按照所需的改名,如(
ps -o pid,ruser=RealUser -o comm=Command
),注意如果出现了改名,后面的格式化关键字必须要用新的-o - 如果所有的列的头部都是空的,如(
ps -o pid= -o comm=
),那么头部就不展示了。 - 对于头部比较宽的会按需要增加列的宽度,这个可能用于增加列宽,如WCHAN(ps -o pid,wchan=WIDE-WCHAN-COLUMN -o comm)
- 同时支持显示的指定宽度,如(ps opid,wchan:42,cmd)
- 如果-o后面带多个列的时候被当做一个或者两个列这种不确定的话,可以直接用多个-o选项。
- 使用PS_FORMAT环境变量来指定一个默认的想要的值。
- o format 指定用户自定义格式,跟-o和–format完全相同
- –format format 用户自定义格式,跟-o和o完全相同
- s 展示信号格式
- u 展示面向用户的格式
- v 展示虚拟内存格式
- X 寄存器格式
- j BSD任务格式
- -j 任务格式
- -M 添加一列安全数据 同 Z(for SELinux)
- Z 添加一列安全数据,跟-M等同(for SELinux)
输出修改
- c 展示真实命令名字
- –cols n
- 设置屏幕宽度
- –columns n
- 设置屏幕宽度
- –cumulative
- 包含一些已经死了的子进程数据(作为其父进程的综述)
- e 在命令后面展示环境变量
- f ASCII艺术流进程层次结构
- –forest ASCII艺术进程树
- h
- -H
- –headers
- k spec
- –lines n
- -n namelist
- 设置namelist文件,等同于N。
- WCHAN的展示需要namelist文件,并且必须严格匹配当前的Linux内核来正确输出。
- 没有这个选项,默认的namelist的搜索路径是
- $PS_SYSMAP
- $PS_SYSTEM_MAP
- /proc/*/wchan
- /boot/System.map-$(uname -r)
- /boot/System.map
- /lib/modules/$(uname -r)/System.map
- /usr/src/linux/System.map
- /System.map
- n WCHAN和USER列都用数字化输出(包含UID和GID的所有类型)
- N namelist
- 指定namelist文件,等同于-n
- –no-headers
- 不打印header
--no-heading
是这个选项的别名
- 不打印header
- O order
- 排序顺序
- –rows n
- 设置屏幕高度
- S
- 从已经结束的子进程统计一些信息汇总到他们的父进程中,例如CPU使用量。
- 这样对于检查一个父进程反复创建短期的子进程来工作的情况非常有用
- –sort spec
- w
- -w
- 宽输出,使用这个选项两次可以获得无限制的宽度
- –width n
- 设置屏幕宽度
线程显示
- H 跟进程一样来展示线程
- -L 展示线程,可能增加 LWP 和 NLWP列
- m 在进程之后展示线程
- -m 在进程之后展示线程
- -T 展示线程,可能跟一列SPID
其他信息
- –info 打印调试信息
- L 列出所有格式说明符
- V 打印procps-ng版本
- -V 打印procps-ng版本
- –version 打印procps-ng版本
注意事项
- ps通过读取/proc下的虚拟文件工作。这个ps不需要
setuid kmem
或者有任何特权来执行。不要给ps任何特殊的权限。 - ps需要访问namelist文件才能正常展示WCHAN。对于2.6之前的内核,必须要安装System.map文件
- CPU使用率当前是表示为这个进程的运行时间和进程的整个生命周期的长度的百分数。这并非理想的,并且不符合ps要遵守的标准。CPU使用率不太可能增加到100%
- SIZE和RSS字段不会计算进程的某些部分,这些部分包含页表、内核栈、thread_info结构体、以及task_struct结构体。这些通常占20KiB的内存,并且是常住内存的。SIZE只是进程的虚拟大小,代码段+数据段+堆栈(code+data+stack)。
- 标记为<defunct>是结束了的进程,也叫做僵尸进程(zombies),是由于其父进程没有适当地销毁他们而留存。如果他们的父进程结束了的话,这些进程将会被init(8)销毁。
- 如果用户名的长度大于展示的列的长度,直接替换成用户的数字ID
- 类似于ps -aux这样的命令选项不推荐使用,因为这个容易引起两种标准的混淆。根据POSIX和Unix标准,上面的命令请求显示所有的带有TTY的进程,再加上所有的为用户x所有的所有进程。如果这个用户不存在则ps将认为你的意思是
ps aux
进程标志
- 这些值展示在F列中,是flags输出说明符提供的:
- 1 fork过了,但是没有exec()
- 4 使用了超级用户权限
进程状态代码
- 下面是 s,stat,state 输出说明符(标题为’STAT’或者’S’)将展示的进程的状态的不同值:
- D 不可中断的休眠(通常是IO)
- R 正在运行或者是可运行的(也就是处在运行队列中的)
- S 可中断的休眠 (等待一个事件完成)
- T 被进程控制信号停止
- t 在追踪(tracing)过程中被调试器停止
- W 正在换页(从2.6.XX内核开始不再有效)
- X 死亡进程(这个永远都看不到的)
- Z 已经结束的进程,或者说是僵尸进程。结束了但是没有被其父进程获取的
- 对于BSD格式以及当使用了stat关键字的时候,可能会展示附加的值:
- < 高优先级 (对其他用户不友善)
- N 低优先级(对其他用户很友善)
- L 有被锁在内存中的页(对于实时的以及定制IO)
- s 是一个会话的老大,这个也经常出现,注意与大写的S区分开
- l 是多线程(使用了CLONE_THREAD 可能是NPTL线程)
- + 是处于前端进程组中的,这个符号经常出现
标准格式说明
这些是用来控制输出的格式的关键字(例如,带有选项-o),可以通过–sort选项排序被选择的进程。
例如: ps -eo pid,user,args --sort user
如下的用户定义的格式说明符可能需要包含空格: args, cmd, comm, command, fname, ucmd, ucomm, lstart, bsdstart, start.
部分关键字并不支持排序的
下面的格式说明符的描述都是3列的,第一列就是在ps命令行中用的选项,第二列是在ps的输出中的标题,第三列是解释这个标题列中的输出的内容究竟是什么意思。
CPU使用率和时间
- %cpu/pcpu %CPU 进程的cpu使用率,以##.#格式展示。当前,这个是通过将CPU时间除以这个进程已经被运行的时间(CPU时间/实际时间),以百分数表示。一般不会增长到100%,除非你很幸运。
- c C 处理器利用率。
- cp CP 每毫米(十分之一)CPU使用率
- cputime/time TIME 累积CPU时间,格式为
[DD-]hh:mm:ss
- bsdtime TIME 累积的CPU时间,用户+系统。显示格式通常为
MMM:SS
但是可能会向右移位,如果进程已经使用超过999分钟的CPU时间。 - bsdstart START 命令启动的时间。如果进程是在低于24H以内启动的,输出格式为
HH:MM
,否则为Mmm:SS
,其中的Mmm是三个字母表示的月份。 - start STARTED 命令启动的时间。如果进程低于24H以内启动的,输出格式为
HH:MM:SS
;否则为Mmm dd
,其中的Mmm是三个字母表示的月份。 - lstart STARTED 命令启动的时间
- start_time START 进程的启动时间或者日期。如果进程不是当年启动的,那么只显示年份。如果不是当天启动的,则显示
MmmDD
或者HH:MM
。 - etime ELAPSED 从进程启动以来经过的时间,格式为[[DD-]hh:]mm:ss
- etimes ELAPSED 从进程启动以来经过的时间,单位为秒。
内存
- %mem/pmem %MEM 进程常驻内存的大小和这台机器上的物理内存的比值,也是以百分数表示
- drs DRS 数据驻留集大小,专用于可执行代码以外的物理内存量。
- trs TRS 文本驻留集大小,专用于可执行代码的物理内存大小
- rss/rssize/rsz RSS/RSS/RSZ 驻留集大小,任务已使用的非交换物理内存(单位是KiB)
- vsize/vsz VSZ 进程的虚拟内存大小,单位为KiB(1024B)。设备映射没有算在内,这个是易于变化的。
- sz SZ 进程的核心镜像的大小,单位是物理页。这个包含代码段.text,数据段.data以及栈空间。当前不包含设备映射空间,这个易改变。
- stackp STACKP 进程的栈顶地址(也就是栈的起始地址)
命令行名字
- args/cmd/command COMMAND 将命令名和所有的参数作为一个字符串。
- 对参数的修改可以从这里展示出来
- 这列的输出可能包含空格
- 一个标记为<defunct>的进程是已经结束了,等着其父进程来完全销毁它。
- 有时候可能命令行参数没法获取到,此时ps将可执行文件用括号括起来打印
- 当最后指定的时候,这列将会被扩展一直到显示屏的边缘。
- comm/ucomm/ucmd COMMAND/COMMAND/CMD 命令名,仅仅只有可执行文件名。对命令名的修改不可见。
- fname COMMAND 进程可执行文件的base名字的前8个字节。此列中的输出可能包含空格。
跟信号相关的
- pending/sig PENDING 待处理信号的掩码。该进程上待处理的信号与各个线程上待处理的信号不同。使用m或者-m选项就两者都可以看到。根据字段的宽度,展示16进制的32或者64位数字。
- caught/sig_catch/sigcatch CAUGHT 捕获信号的掩码。根据字段的宽度,展示32位或者64位的16进制格式的掩码。
- blocked/sig_block/sigmask BLOCKED 阻塞信号的掩码。根据字段的宽度,展示32位或者64位的16进制格式的掩码。
- ignored/sig_ignore/sigignore IGNORED 忽略信号的掩码。根据字段的宽度,展示十六进制的32或者64位的掩码。
跟处理器调度相关的
- nwchan WCHAN 让这个进程休眠的内核函数的地址。正在运行中的任务将在这个列输出一个-。
- wchan WCHAN 让这个进程休眠的内核函数的名字。
- - 进程正在运行
- * 此进程是一个多线程程序并且ps没有按照线程输出
- lwp/spid/tid LWP/SPID/TID 轻量级进程(线程)可分派实体的ID。这个值可能也会作为以下的情况而出现:
- 进程ID(pid)
- 进程组ID(pgrp)
- 会话的老大的会话ID(sid)
- 线程组的老大的线程线程组ID(tgid)
- 进程组老大的终端进程组ID(tpgid)
- nlwp/thcount NLWP/THCNT 进程持有的内核线程数量
- machine MACHINE 如果包含了systemd的支持,展示进程分配到的VM或者容器的机器名字。
- maj_flt MAJFLT 此进程发生的主要页面错误的数量。
- min_flt MINFLT 此进程发生的次要页面错误的数量。
- ni/nice NI nice值,从19(最友善,优先级最低)到-20(最不友善,优先级最高)
- class/cls/policy CLS//POL 进程的调度类,这个字段的可能值为:
- - 没有报告
- TS SCHED_OTHER
- FF SCHED_FIFO
- RR SCHED_RR
- B SCHED_BATCH
- ISO SCHED_ISO
- IDL SCHED_IDLE
- ? 未知的值
- sched SCH 进程的调度策略,展示出来的是数字,对应关系如下:
- SCHED_OTHER(SCHED_NORMAL) 0
- SCHED_FIFO 1
- SCHED_RR 2
- SCHED_BATCH 3
- SCHED_ISO 4
- SCHED_IDLE 5
- f/flags/flag F 进程关联的标志
- pid/tgid PID/TGID 表示进程ID的数字。表示一个任务属于的线程组。是线程组老大的进程ID。
- ppid PPID 父进程ID
- pgid/pgrp PGID/PGRP 进程组ID,或者说就是进程组的老大的进程ID。
- pri PRI 进程的优先级,值越大优先级越低
- psr PSR 进程当前分配到的处理器
- eip EIP 指令指针
- esp ESP 栈指针
- rtprio RTPRIO 实时优先级
- s/state S 最小状态显示(1个字符)
- stat STAT 多字符进程状态。状态的具体描述在进程状态码中描述了。s和state只会显示一个字符。
- uunit UUNIT 展示进程所属的用户单元(需要包含systemd支持)。
- unit UNIT 展示进程所属的单元(需要包含systemd支持)
- tty/tt/tname TT/TT/TTY 控制终端
- tpgid TPGID 进程连接到的终端上的前端进程组的ID,如果此进程没有连接到任何终端则为-1.
- sgi_p P 执行当前进程的处理器。如果进程当前没有正在执行或者不是Runnable状态的话,展示*
- slice SLICE 展示进程属于的slice单元(需要包含systemd支持)
跟各种用户ID相关的
- euid/uid EUID/UID 有效用户ID
- euser/uname/user EUSER/USER/USER 有效用户名。如果可以直接获取到并且字段的宽度允许的话,是一个文本ID,否则就是一个十进制的数字。n选项强制十进制表示。
- egid/gid EGID 进程的有效组ID号码,是一个十进制整数
- egroup/group EGROUP 进程的有效组ID,如果可以直接获取到并且字段的宽度允许的话,是一个文本的组ID,否则就是一个十进制的数字。
- fuid/fsuid FUID 文件系统访问用户ID
- fuser FUSER 文件系统访问用户ID 这个优先展示文本格式的用户ID,如果不能展示则展示十进制数字
- fgid/fsgid FGID 文件系统访问组ID
- fgroup FGROUP 文件系统访问组ID,优先显示文本组ID,如果获取不到或者宽度不够则展示十进制数字
- ouid OWNER 如果包含了systemd支持,则展示进程的会话的拥有者的Unix用户标识。
- rgid RGID 实际组ID
- rgroup RGROUP 实际组的名字。如果宽度允许,也能获取到时,直接展示文本内容;否则展示十进制的数字。
- ruid RUID 实际用户ID
- ruser RUSER 实际用户ID 如果宽度允许,也能获取到时,直接展示文本内容;否则展示十进制的数字。
- suid/svuid SUID/SVUID 保存的用户ID
- suser SUSER 保存的用户名称。如果宽度允许,也能获取到时,直接展示文本内容;否则展示十进制的数字。
- supgid SUPGID 如果补充组存在的话,就是补充组ID。参考getgroups(2)
- supgrp SUPGRP 如果补充组存在的话,就是补充组的名字。
- sgid/svgid SGID/SVGID 保存的组ID
- sgroup SGROUP 保存的组名字。如果宽度允许,也能获取到时,直接展示文本内容;否则展示十进制的数字。
- sess/session/sid SESS//SID 会话ID或者是会话老大的进程ID
- lsession SESSION 如果包含了systemd的支持的话,展示进程的登录会话的标识。
跟名字空间相关的
- ipcns IPCNS 描述进程属于的名字空间的唯一的节点号码
- mntns MNTNS 描述进程属于的名字空间的唯一节点号码
- netns NETNS 描述进程属于的名字空间的唯一节点号码
- pidns PIDNS 描述进程属于的名字空间的唯一节点号码
- utsns UTSNS 描述进程属于的名字空间的唯一节点号码
- userns USERNS 描述进程属于的名字空间的唯一节点号码
- cgroup CGROUP 展示进程所属于的控制组。
其他类
- label LABEL 安全标签,常用于SELinux上下文数据中。这个用来在高安全系统中给MAC(Mandatory-Access-Control)查找
环境变量
跟ps相关的环境变量
- 通常不要去动这些环境变量。例如CMD_ENV或者PS_PERSONALITY,这个可能设置系统为Linux。没有这种环境变量,ps继续沿用Unix98标准中的那些无用部分。
命令使用总结
这个命令的用法整体就是如下的格式
ps <选择要展示的进程> <选择待展示进程中要展示的格式或者说要展示的内容>
- 进程选择
- 简单进程选择
- 列表方式的进程选择
- 要展示的内容
- 字段说明