> For the complete documentation index, see [llms.txt](https://man.bsdcn.org/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://man.bsdcn.org/man1/ps.1.md).

# ps(1)

`ps` — 进程状态

## 名称

`ps`

## 概要

`ps [--libxo] [-AaCcdefHhjlmrSTuvwXxZ] [-O fmt] [-o fmt] [-D up | down | both] [-G gid[,gid...]] [-J jid[,jid...]] [-M core] [-N system] [-p pid[,pid...]] [-t tty[,tty...]] [-U user[,user...]]`

`ps [--libxo] -L`

## 描述

`ps` 实用程序显示所选进程的信息。其传统文本风格输出由一个标题行后跟每个所选进程一行信息组成，如果使用 `-H` 则可能有多行（每个轻量级进程一行）。其他输出风格可通过 `--libxo` 请求。

默认情况下，仅显示调用用户的进程（通过将其有效用户 ID 与 `ps` 进程的有效用户 ID 匹配来判定），且仅显示拥有控制终端的进程。通过组合使用 `-A`、`-a`、`-D`、`-G`、`-J`、`-p`、`-T`、`-t`、`-U`、`-X` 和 `-x` 选项，可选择不同的进程集合进行显示。除 `-X` 和 `-x` 选项外，只要其中一个出现，就会抑制默认的进程选择，即调用用户的进程仅在请求时才显示。如果这些选项中出现多个（同样有相同例外），`ps` 会选择至少被其中一个匹配到的进程（inclusive OR）。`-X` 选项可独立使用，以进一步过滤所列进程，仅保留拥有控制终端的进程（通过 `-p` 选择的除外）。其对立选项 `-x` 强制移除该过滤器。如果未指定 `-X` 和 `-x` 中的任何一个，则隐含的默认行为是 `-X`，除非使用另一个其描述明确说明隐含 `-x` 的选项。

对于每个所选进程，默认显示的信息包括进程 ID、控制终端、状态、CPU 时间（包括用户时间和系统时间）以及相关联的命令（参见下文 `command` 关键字的文档）。此信息可使用两组可按需组合的选项来调整。首先，`-o` 和 `-O` 选项添加与显式传递的关键字相对应的数据列。可用关键字记录在下文 Sx KEYWORDS（关键字）小节。可使用 `-L` 选项列出它们。其次，`-j`、`-l`、`-u` 和 `-v` 选项指定特定的预定义列组，也称为 canned displays（预置显示）。这些选项中任何一个的出现都会抑制默认显示，将其全部替换为所请求的列，并按选项传递的顺序排列。通过预置显示选项请求的、与先前预置显示选项或命令行中任何位置显式 `-O` 或 `-o` 选项所添加列具有相同关键字或别名关键字的单个列，都会被抑制。这种预置显示中重复数据的自动移除对于微调这些显示和/或组合多个显示而无需从头重建变体（例如仅使用 `-o` 选项）很有用。

输出信息行默认首先按控制终端排序，然后按进程 ID 排序，最后（如果指定了 `-H`）按轻量级进程（线程）ID 排序。`-m`、`-r`、`-u` 和 `-v` 选项会更改排序顺序。如果给定了多个排序选项，则所选进程按最后指定的排序选项排序。

如果使用传统文本输出（默认），默认输出宽度为 `COLUMNS` 环境变量所请求的宽度（如果存在），否则为与 `ps` 进程关联的终端的行宽（如果有）。在所有其他情况下，输出宽度不受限制。另见 `-w` 选项和 Sx BUGS（缺陷）小节。

为了向后兼容，`ps` 尝试将任何位置参数解释为进程 ID，如同由 `-p` 选项指定。无法如此解释时会触发错误。`ps` 还接受旧式 BSD 选项，其格式和效果有意不在此文档中说明。

选项如下：

**`--libxo`** 通过 libxo(3) 以多种人类和机器可读格式生成输出。命令行参数的细节参见 xo\_options(7)。默认为传统文本风格输出。

**`-A`** 显示系统中所有进程的信息。使用此选项严格等价于同时指定 `-a` 和 `-x`。更多信息请参见它们的说明。

**`-a`** 显示所有用户的进程的信息。但它不会列出所有进程（参见 `-A` 和 `-x`）。如果 `security.bsd.see_other_uids` sysctl 设置为零，仅当 `ps` 进程的实际用户 ID 为 0 时才生效。

**`-C`** 通过使用忽略“resident”时间的“raw”CPU 计算方式来更改 CPU 百分比的算法（通常无效果）。

**`-c`** 将“command”列的输出更改为仅包含可执行文件名，而非完整命令行。

**`-D`** 基于进程树扩展所选进程列表。“UP”会添加祖先进程，“DOWN”会添加后代进程，“BOTH”会同时添加祖先和后代进程。`-D` 不隐含 `-d`，但与之配合良好。

**`-d`** 将进程按后代顺序排列，并以缩进文本作为树前缀，显示兄弟和父/子关系。如果同时使用了 `-m` 和 `-r` 选项中的一个，它们控制兄弟进程之间的相对排序。注意，如果最后一列的关键字不是 `comm`、`command` 或 `ucomm`，此选项无效。

**`-e`** 同时显示环境。

**`-f`** 指示在 `command` 列中打印完整命令和参数。这是 FreeBSD 上的默认行为。参见 `-c` 以关闭它。

**`-G`** 显示真实组 ID 与指定组 ID 或名称匹配的进程的信息。默认隐含 `-x`。

**`-H`** 显示与每个进程关联的所有线程。

**`-h`** 必要时重复信息标题，以保证每页信息有一个标题。

**`-J`** 显示匹配指定 jail ID 的进程的信息。这可以是 jail 的 `jid` 或 `name`。使用 `-J` **0** 请求显示主机进程。默认隐含 `-x`。

**`-j`** 打印与以下关键字关联的信息：`user`、`pid`、`ppid`、`pgid`、`sid`、`jobc`、`state`、`tt`、`time` 和 `command`。

**`-L`** 列出 `-O` 和 `-o` 选项可用的关键字集合。

**`-l`** 显示与以下关键字关联的信息：`uid`、`pid`、`ppid`、`cpu`、`pri`、`nice`、`vsz`、`rss`、`mwchan`、`state`、`tt`、`time` 和 `command`。

**`-M`** 从指定的 core 而非当前运行的系统中提取与名称列表关联的值。

**`-m`** 按内存使用量排序，而非按控制终端和进程 ID 的组合排序。

**`-N`** 从指定的系统而非默认系统（即系统启动时所用的内核镜像）中提取名称列表。

**`-O`** 将传递的列保存到一个单独的列表中，该列表最终会嫁接到由其他选项指定的进程 ID 列首次出现处之后（若无则默认显示）。如果由其他选项准备的显示不含进程 ID 列，该列表插入到显示的开头。后续出现的 `-O` 会追加到待嫁接的列列表。此选项接受以空格或逗号分隔的关键字列表。列表中最后一个关键字可附加一个等号（`=`），如 `-o` 选项所说明的那样，效果相同。

**`-o`** 显示与指定的以空格或逗号分隔的关键字列表关联的信息。列表中最后一个关键字可附加一个等号（`=`）和一个跨该参数其余部分的字符串，该字符串可包含空格和逗号字符。这会使打印的标题使用指定的字符串而非标准标题。多个关键字也可以通过多个 `-o` 选项的形式给出。因此可以更改多个关键字的标题文本。如果所有关键字的标题文本都为空，则不写入标题行。

**`-p`** 显示匹配指定进程 ID 的进程的信息。通过此选项选择的进程不受 `-X` 过滤。

**`-r`** 按当前 CPU 使用率排序，而非按控制终端和进程 ID 的组合排序。

**`-S`** 通过将所有已退出的子进程计入其父进程来更改进程时间（即 cputime、systime 和 usertime）的计算方式。

**`-T`** 显示附加到与标准输入关联的设备上的进程的信息。

**`-t`** 显示附加到指定终端设备上的进程的信息。可指定完整路径名以及缩写（参见 `tt` 关键字的说明）。默认隐含 `-x`。

**`-U`** 显示真实用户 ID 与指定用户 ID 或名称匹配的进程的信息。默认隐含 `-x`。

**`-u`** 显示与以下关键字关联的信息：`user`、`pid`、`%cpu`、`%mem`、`vsz`、`rss`、`tt`、`state`、`start`、`time` 和 `command`。`-u` 选项隐含 `-r` 选项。

**`-v`** 显示与以下关键字关联的信息：`pid`、`state`、`time`、`sl`、`re`、`pagein`、`vsz`、`rss`、`lim`、`tsiz`、`%cpu`、`%mem` 和 `command`。`-v` 选项隐含 `-m` 选项。

**`-w`** 使用至少 131 列显示信息。如果 `-w` 指定多次，`ps` 会使用所需数量的列。关于输出宽度的初始判定，请参见本手册页的序言。特别地，如果初始输出宽度不受限制，指定 `-w` 无效。另请参阅 Sx BUGS（缺陷）小节。

**`-X`** 当显示由其他选项选择的进程时，跳过任何没有控制终端的进程，通过 `-p` 选择的除外。这是默认行为，除非使用另一个其描述明确说明隐含 `-x` 的选项。

**`-x`** 当显示由其他选项选择的进程时，包含没有控制终端的进程。此选项的行为与 `-X` 相反。如果同时指定了 `-X` 和 `-x`，`ps` 会服从最后出现的那个。

**`-Z`** 将 [mac(4)](/man4/mac.4.md) 标签添加到 `ps` 将显示信息的关键字列表中。

## 关键字

以下是可用关键字及其含义的完整列表。其中几个有别名（同义关键字）。部分关键字的详细说明可在列表之后找到。

**`%cpu`** CPU 使用百分比（别名 `pcpu`）

**`%mem`** 内存使用百分比（别名 `pmem`）

**`acflag`** 记账标志（别名 `acflg`）

**`args`** 命令和参数

**`class`** 登录类

**`comm`** 命令

**`command`** 命令和参数

**`cow`** 写时复制缺页数

**`cpu`** 进程正在其上执行的处理器编号（仅在 SMP 系统上可见）。

**`dsiz`** 数据大小（KiB）

**`emul`** 系统调用模拟环境（ABI）

**`etime`** 经过运行时间，格式为“\[days-]\[hours:]minutes:seconds”

**`etimes`** 经过运行时间，以十进制整数秒表示

**`fib`** 默认 FIB 编号，参见 setfib(1)

**`flags`** 进程标志，以十六进制表示（别名 `f`）

**`flags2`** 附加的进程标志集，以十六进制表示（别名 `f2`）

**`gid`** 有效组 ID（别名 `egid`）

**`group`** 组名（来自 egid）（别名 `egroup`）

**`inblk`** 读取的总块数（别名 `inblock`）

**`jail`** jail 名称

**`jid`** jail ID

**`jobc`** 作业控制计数

**`ktrace`** 跟踪标志

**`label`** MAC 标签

**`lim`** memoryuse 限制

**`lockname`** 当前被阻塞的锁（以符号名称表示）

**`logname`** 启动会话的用户的登录名

**`lstart`** 启动时间

**`lwp`** 线程（轻量级进程）ID（别名 `tid`）

**`majflt`** 总缺页数

**`minflt`** 总页面回收数

**`msgrcv`** 接收的消息总数（从管道/套接字读取）

**`msgsnd`** 发送的消息总数（写入管道/套接字）

**`mwchan`** 当前被阻塞的等待通道或锁

**`nice`** nice 值（别名 `ni`）

**`nivcsw`** 总非自愿上下文切换数

**`nlwp`** 绑定到进程的线程（轻量级进程）数

**`nsigs`** 接收的信号总数（别名 `nsignals`）

**`nswap`** 总换入/换出次数

**`nvcsw`** 总自愿上下文切换数

**`nwchan`** 等待通道（以地址表示）

**`oublk`** 写入的总块数（别名 `oublock`）

**`paddr`** 进程指针

**`pagein`** 页面调入数（与 majflt 相同）

**`pgid`** 进程组编号

**`pid`** 进程 ID

**`ppid`** 父进程 ID

**`pri`** 调度优先级

**`re`** 核心驻留时间（秒；127 = 无穷大）

**`rgid`** 真实组 ID

**`rgroup`** 组名（来自 rgid）

**`rss`** 驻留集大小（KiB）

**`rtprio`** 实时优先级（参见 rtprio(1)）

**`ruid`** 真实用户 ID

**`ruser`** 用户名（来自 ruid）

**`sid`** 会话 ID

**`sig`** 待处理信号（别名 `pending`）

**`sigcatch`** 捕获的信号（别名 `caught`）

**`sigignore`** 忽略的信号（别名 `ignored`）

**`sigmask`** 阻塞的信号（别名 `blocked`）

**`sl`** 睡眠时间（秒；127 = 无穷大）

**`ssiz`** 栈大小（KiB）

**`start`** 启动时间

**`state`** 符号进程状态（别名 `stat`）

**`svgid`** 来自 setgid 可执行文件的已保存 gid

**`svuid`** 来自 setuid 可执行文件的已保存 UID

**`systime`** 累计系统 CPU 时间

**`tdaddr`** 线程地址

**`tdname`** 线程名

**`tdev`** 控制终端设备号

**`time`** 累计 CPU 时间，用户 + 系统（别名 `cputime`）

**`tpgid`** 控制终端进程组 ID

**`tracer`** 跟踪进程 ID

**`tsid`** 控制终端会话 ID

**`tsiz`** 文本大小（KiB）

**`tt`** 控制终端名（两个字母的缩写）

**`tty`** 控制终端的全名

**`ucomm`** 用于记账的进程名

**`uid`** 有效用户 ID（别名 `euid`）

**`upr`** 从系统调用返回时的调度优先级（别名 `usrpri`）

**`uprocp`** 进程指针

**`user`** 用户名（来自 UID）

**`usertime`** 累计用户 CPU 时间

**`vmaddr`** vmspace 指针

**`vsz`** 虚拟大小（KiB）（别名 `vsize`）

**`wchan`** 等待通道（以符号名称表示）

**`xstat`** 退出或停止状态（仅对已停止或僵尸进程有效）

其中一些关键字进一步说明如下：

`#include <sys/proc.h>`

| `P_ADVLOCK`         | 0x00000001 | 进程可能持有 POSIX 咨询锁                   |
| ------------------- | ---------- | ---------------------------------- |
| `P_CONTROLT`        | 0x00000002 | 拥有控制终端                             |
| `P_KPROC`           | 0x00000004 | 内核进程                               |
| `P_PPWAIT`          | 0x00000010 | 父进程在等待子进程 exec/exit                |
| `P_PROFIL`          | 0x00000020 | 已启动性能分析                            |
| `P_STOPPROF`        | 0x00000040 | 有线程请求停止性能分析                        |
| `P_HADTHREADS`      | 0x00000080 | 曾拥有线程（无清理捷径）                       |
| `P_SUGID`           | 0x00000100 | 自上次 exec 以来曾拥有 setid 特权            |
| `P_SYSTEM`          | 0x00000200 | 系统进程：无信号、统计或交换                     |
| `P_SINGLE_EXIT`     | 0x00000400 | 挂起的线程应退出，而非等待                      |
| `P_TRACED`          | 0x00000800 | 被调试的进程正在被跟踪                        |
| `P_WAITED`          | 0x00001000 | 有人在等待我们                            |
| `P_WEXIT`           | 0x00002000 | 正在退出                               |
| `P_EXEC`            | 0x00004000 | 进程调用过 exec                         |
| `P_WKILLED`         | 0x00008000 | 已被杀死，应尽快到达内核/用户边界                  |
| `P_CONTINUED`       | 0x00010000 | 进程已从停止状态继续                         |
| `P_STOPPED_SIG`     | 0x00020000 | 因 SIGSTOP/SIGTSTP 而停止              |
| `P_STOPPED_TRACE`   | 0x00040000 | 因跟踪而停止                             |
| `P_STOPPED_SINGLE`  | 0x00080000 | 仅一个线程可继续                           |
| `P_PROTECTED`       | 0x00100000 | 内存超额提交时不被杀死                        |
| `P_SIGEVENT`        | 0x00200000 | 进程待处理信号已更改                         |
| `P_SINGLE_BOUNDARY` | 0x00400000 | 线程应在用户边界挂起                         |
| `P_HWPMC`           | 0x00800000 | 进程正在使用 HWPMC                       |
| `P_JAILED`          | 0x01000000 | 进程在 jail 中                         |
| `P_TOTAL_STOP`      | 0x02000000 | 因系统挂起而停止                           |
| `P_INEXEC`          | 0x04000000 | 进程在 execve(2) 中                    |
| `P_STATCHILD`       | 0x08000000 | 子进程已停止或退出                          |
| `P_INMEM`           | 0x10000000 | 总是设置，未使用                           |
| `P_PPTRACE`         | 0x80000000 | vfork 出的子进程发出了 ptrace(PT\_TRACEME) |

`#include <sys/proc.h>`

| `P2_INHERIT_PROTECTED`    | 0x00000001 | 新子进程获得 P\_PROTECTED          |
| ------------------------- | ---------- | ---------------------------- |
| `P2_NOTRACE`              | 0x00000002 | 不可 ptrace(2) 附加或 coredump    |
| `P2_NOTRACE_EXEC`         | 0x00000004 | execve(2) 后保留 P2\_NOPTRACE   |
| `P2_AST_SU`               | 0x00000008 | 为 kthread 处理 SU ast          |
| `P2_PTRACE_FSTP`          | 0x00000010 | 来自 PT\_ATTACH 的 SIGSTOP 尚未处理 |
| `P2_TRAPCAP`              | 0x00000020 | ENOTCAPABLE 时触发 SIGTRAP      |
| `P2_ASLR_ENABLE`          | 0x00000040 | 强制启用 ASLR                    |
| `P2_ASLR_DISABLE`         | 0x00000080 | 强制禁用 ASLR                    |
| `P2_ASLR_IGNSTART`        | 0x00000100 | 启用 ASLR 占用 sbrk 区域           |
| `P2_PROTMAX_ENABLE`       | 0x00000200 | 强制启用隐含 PROT\_MAX             |
| `P2_PROTMAX_DISABLE`      | 0x00000400 | 强制禁用隐含 PROT\_MAX             |
| `P2_STKGAP_DISABLE`       | 0x00000800 | 为 MAP\_STACK 禁用栈间隙           |
| `P2_STKGAP_DISABLE_EXEC`  | 0x00001000 | exec 后栈间隙被禁用                 |
| `P2_ITSTOPPED`            | 0x00002000 | itimer 已停止（作为进程停止的一部分）       |
| `P2_PTRACEREQ`            | 0x00004000 | 活动的 ptrace 请求                |
| `P2_NO_NEW_PRIVS`         | 0x00008000 | exec 时忽略 setuid              |
| `P2_WXORX_DISABLE`        | 0x00010000 | 启用 W^X 映射                    |
| `P2_WXORX_ENABLE_EXEC`    | 0x00020000 | exec 后启用 W^X                 |
| `P2_WEXIT`                | 0x00040000 | 内部早期退出状态                     |
| `P2_REAPKILLED`           | 0x00080000 | REAP\_KILL 轮次已处理该进程          |
| `P2_MEMBAR_PRIVE`         | 0x00100000 | 已注册 membarrier 私有加速          |
| `P2_MEMBAR_PRIVE_SYNCORE` | 0x00200000 | 已注册 membarrier 私有加速同步核心      |
| `P2_MEMBAR_GLOBE`         | 0x00400000 | 已注册 membar 全局加速              |

**`D`** 标记处于磁盘（或其他短期、不可中断）等待状态的进程。

**`I`** 标记空闲进程（睡眠时间超过约 20 秒）。

**`L`** 标记正在等待获取锁的进程。

**`R`** 标记可运行的进程。

**`S`** 标记睡眠时间少于约 20 秒的进程。

**`T`** 标记已停止的进程。

**`W`** 标记空闲的中断线程。

**`Z`** 标记已死亡的进程（“zombie”，即僵尸）。

**`+`** 进程在其控制终端的前台进程组中。

**`<`** 进程已提高 CPU 调度优先级。

**`C`** 进程处于 [capsicum(4)](/man4/capsicum.4.md) 能力模式。

**`E`** 进程正试图退出。

**`J`** 标记处于 jail(2) 中的进程。监狱的主机名可在 **`/proc/`**`pid`**`/status`** 中找到。

**`L`** 进程有锁定在核心中的页面（例如用于原始 I/O）。

**`N`** 进程已降低 CPU 调度优先级（参见 setpriority(2)）。

**`s`** 进程是会话首领。

**`V`** 进程的父进程在 vfork(2) 期间被挂起，等待该进程 exec 或 exit。

**`X`** 进程正在被跟踪或调试。

**`%cpu`** 进程的 CPU 利用率；这是对最多一分钟先前（实际）时间的衰减平均值。由于计算所基于的时间基准会变化（因为进程可能非常年轻），所有 `%cpu` 字段之和可能超过 100%。

**`%mem`** 此进程使用的真实内存百分比。

**`class`** 与进程关联的登录类。

**`command`** 打印的命令和参数按以下方式确定。已退出但其父进程尚未等待它的进程（换言之，僵尸进程）显示为“`<defunct>`”。如果无法定位参数（通常因为它们尚未设置，系统进程和/或内核线程即如此），命令名以方括号打印。`ps` 实用程序首先尝试获取内核缓存的参数（如果它们短于 `kern.ps_arg_cache_limit` sysctl 的值）。进程可通过 setproctitle(3) 更改显示的参数。否则，`ps` 通过检查内存或交换区对进程创建时给定的文件名和参数做出有根据的猜测。此方法本身就有些不可靠，且无论如何进程都有权销毁此信息。但 `ucomm` 关键字（记账用）可以依赖。如果参数不可用或与 `ucomm` 关键字不一致，`ucomm` 关键字的值会以括号形式追加到参数后。

**`flags`** 与进程关联的标志，如包含文件所示

**`flags2`** 保存在 `p_flag2` 中、与进程关联的标志，如包含文件所示

**`label`** 进程的 MAC 标签。

**`lim`** 内存使用的软限制，通过调用 setrlimit(2) 指定。

**`lstart`** 命令启动的确切时间，使用 strftime(3) 中描述的 `%c` 格式。

**`lockname`** 进程当前被阻塞的锁的名称。如果名称无效或未知，则显示 “???”。

**`logname`** 与进程所在会话关联的登录名（参见 getlogin(2)）。

**`mwchan`** 进程正常阻塞时的事件名，或进程在锁上阻塞时的锁名。详情参见 wchan 和 lockname 关键字。

**`nice`** 进程调度增量（参见 setpriority(2)）。

**`rss`** 进程的真实内存（驻留集）大小（KiB）。

**`start`** 命令启动的时间。如果命令在 24 小时内启动，启动时间使用 strftime(3) 中描述的 “`%H:%M`” 格式显示。如果命令在 7 天内启动，启动时间使用 “`%a%H`” 格式显示。否则，启动时间使用 “`%e%b%y`” 格式显示。

**`sig`** 如果未指定 `-H` 选项，则为进程队列中待处理信号的位掩码，否则为每个线程的待处理信号队列。

**`state`** 状态由一系列字符给出，例如 “`RWNA`”。第一个字符表示进程的运行状态：之后这些字符之后的任何附加字符（如果有）表示附加的状态信息：

**`tt`** 控制终端路径名的缩写（如果有）。该缩写由 **`/dev/tty`** 后的三个字母组成，或对于伪终端，为 **`/dev/pts`** 中的对应条目。如果进程不再能到达该控制终端（即已被吊销），则后跟一个 “`-`”。不带前导两个字母缩写或伪终端设备号的 “`-`” 表示一个从未拥有控制终端的进程。控制终端的完整路径名可通过 `tty` 关键字获得。

**`wchan`** 进程等待的事件（系统中的地址）。以数字打印时，地址的初始部分被截断，结果以十六进制打印，例如 0x80324000 打印为 324000。

## 环境变量

以下环境变量影响 `ps` 的执行：

**`COLUMNS`** 如果设置，指定用户偏好的输出宽度（以列位置计）。仅影响传统文本风格输出。关于最终输出宽度如何判定，请参见本手册页的序言。

## 文件

**`/boot/kernel/kernel`** 默认系统名称列表

## 退出状态

`ps` 实用程序成功时退出值为 0，发生错误时大于 0。

## 实例

显示所有系统进程的信息：

```sh
$ ps -auxw
```

## 参见

[kill(1)](/man1/kill.1.md), pgrep(1), pkill(1), [procstat(1)](/man1/procstat.1.md), [w(1)](/man1/w.1.md), [kvm(3)](/misc/kvm.3.md), [libxo(3)](/misc/libxo.3.md), [strftime(3)](/stdtime/strftime.3.md), [xo\_options(7)](/man7/xo_options.7.md), [mac(4)](/man4/mac.4.md), [procfs(4)](/man4/procfs.4.md), pstat(8), [sysctl(8)](/man8/sysctl.8.md), [mutex(9)](/man9/mutex.9.md)

## 标准

由于历史原因，FreeBSD 下的 `ps` 实用程序支持的选项集与 -p1003.1-2024 所描述以及非 BSD 操作系统所支持的不同。

特别地，与此实现相反，POSIX 规定选项 `-d` 应用于选择除会话首领之外的所有进程，选项 `-e` 选择所有进程（等价于 `-A`），选项 `-u` 按有效用户 ID 选择进程。

然而，选项 `-A`、`-a`、`-G`、`-l`、`-o`、`-p`、`-U` 和 `-t` 的行为与 -p1003.1-2024 规定一致。选项 `-f` 和 `-w` 当前不一致，但未来可能会改为一致。

POSIX 的选项 `-g`（用于选择以指定进程为会话首领的进程）未实现。然而，提供此功能的其他 UNIX 系统通过选项 `-s` 实现，将 `-g` 保留用于按组首领查询。

## 历史

`ps` 命令出现于 Version 3 AT\&T UNIX，最初位于手册的第 8 节。

## 缺陷

由于 `ps` 无法比系统运行得更快，且作为任何其他被调度的进程运行，其显示的信息永远不可能是精确的。

`ps` 当前未正确限制输出宽度，在大多数情况下根本不限制。无论目标宽度如何，请求的列总是全部打印，且宽度允许完整打印其最长值，除非关键字为 `command` 或 `args` 的列不在显示的最后（它们被截断为 16 字节），以及显示中最后一列的关键字请求变长文本信息时（如 `command`、`jail` 和 `user` 关键字所做）。这极大地限制了终端宽度对输出的影响和作用，相应地也限制了 `COLUMNS` 环境变量和 `-w` 选项（如果仅指定一次）的影响和作用。

`ps` 实用程序不能正确显示包含多字节字符的参数列表。
