%% # 纲要 > 主干纲要、Hint/线索/路标 # Q&A #### 已明确 #### 待明确 > 当下仍存有的疑惑 **❓<font color="#c0504d"> 有什么问题?</font>** # Buffer ## 闪念 > sudden idea ## 候选资料 > Read it later %% <br><br> # 进程处理 #### 查询进程 PID—— pgrep `pgrep [options] pattern` :根据指定 pattern 搜索进程,返回匹配的**进程 PID** 选项: - `-f|--full`: 使用 `pattern` 指定的**完整命令行**进行搜索,而不仅是进程名。 - `-u|--uid`: 指定 UID,限制搜索范围为特定用户的进程 ```shell pgrep ssh # 查找名为ssh的进程的PID pgrep -u username # 查找特定用户的进程 pgrep -f /path/to/command # 使用完整的运行命令行进行搜索 ``` > [!example] 根据进程名查询其 PID > ![[_attachment/02-开发笔记/11-Linux/Linux 命令行/Linux-进程相关命令.assets/IMG-Linux-进程相关命令-45084ABEB1A6FD50D56B06D523DF3BB2.png|527]] #### 向进程发送信号——kill、pkill 命令 ##### kill 命令 `kill [option] <pid>[...]` : 按 **PID** 向指定进程发送信号(默认为 `SIGTERM(15)` **请求终止**信号) 选项: - `-l`:查看**信号列表** - `-<signal>` 以**信号值**标识信号,例如: - `-9`: 发送`SIGKILL(9)` 信号,强制终止 - `-19`:发送 `SIGSTOP(19)` 信号,强制暂停 - `-18`:发送 `SIGCONT(18)` 信号,恢复被暂停的进程 - `-s <signal>` 以**信号名**标识,例如`SIGKILL` 或 `KILL` 等: - `-s KILL` | `-s SIGKILL` :发送`SIGKILL(9)` 信号,强制终止 - `-s STOP` | `-s SIGSTOP` :发送 `SIGSTOP(19)` 信号,强制暂停 - `-s CONT` | `-s SIGCONT`:发送 `SIGCONT(18)` 信号,恢复被暂停的进程 ```shell kill <PID> # 默认发送"TERM"信号(值为15), 请求终止. kill -9 <PID> # 发送"KILL"信号(值为9), 表示"无条件终止" kill -s KILL <PID> # 与上等价 kill -1 <PID> # 与上等价 kill -s HUP <PID> # 将进程挂起 ``` > [!note] `kill -l` 查看信号列表 > ![[_attachment/02-开发笔记/11-Linux/Linux 命令行/Linux-进程相关命令.assets/IMG-Linux-进程相关命令-B3F02F913A5A7E1B2C516431B4B08B6D.png|845]] ##### pkill 命令 `$ pkill <p_name>` 按 **进程名** 向指定进程发送信号(默认为 `SIGTERM(15)` 请求终止信号) 选项: - `-f|--full`: 使用 `pattern` 指定的**完整命令行**进行搜索,而不仅是进程名。 ```shell # 向所有名为python的进程发送 "TERM"信号 pkill python # "-f"参数表示匹配完整的命令行,而不仅是程序名. pkill -f <full_command> # kill掉所有启动命令为 "python3 -u run_train.py"的进程 pkill -f "python3 -u run_train.py" ``` <br><br> # 后台作业控制 #### 以后台方式运行——& `command &`:命令后加上`&` 符号,表示在**后台**运行该命令 <br> #### 查看后台作业信息——jobs `$ jobs [options]`:查看 **当前 shell 中的后台作业**(仍在运行或已停止的后台作业) 选项: - `-l`:显示每个后台作业的 **PID** - `-p`:仅显示每个作业的 PID - `-n`:仅列出**有状态变化**的作业(例如刚停止或刚恢复) - `-r`:只列出**正在运行**的作业(Running) - `-s`:只列出**已停止**的作业 > [!NOTE] jobs 显示说明——默认共三个字段:**后台作业号**、**进程状态**、**进程启动命令** > > 作业号标识: > > - `+`:**默认作业/当前作业**。使用 fg 或 bg 命令而不带作业号时,**默认即操作该作业**。 > - `-`:**上一个作业**。即 "**默认作业**" 之前的作业,默认作业结束后,**该作业就会变为新的默认作业**。 > > 进程状态有三种:Running、Stopped、Done > > ![[_attachment/02-开发笔记/11-Linux/Linux 命令行/Linux-进程相关命令.assets/IMG-Linux-进程相关命令-65F3A6D2CAFCA1AA58D72FC23F6DE341.png|570]] > [!info] jobs 会列出以下作业 > > - 当前 shell 中使用 `&` 启动的后台任务 > - 当前 shell 中被 `Ctrl+Z` 暂停的前台任务(进入后台、状态为 Stopped) > > ![[_attachment/02-开发笔记/11-Linux/Linux 命令行/Linux-进程相关命令.assets/IMG-Linux-进程相关命令-20B7D1D10C4557D4E953C8E44422DFA8.png|457]] > > ![[_attachment/02-开发笔记/11-Linux/Linux 命令行/Linux-进程相关命令.assets/IMG-Linux-进程相关命令-90DBCDC8718C7FA13F4C8CF4FD2D987C.png|464]] > <br> #### 前后台作业控制——fg、bg - `fg %[job_id]`:将后台任务 **切回==前台==继续运行**。 - `bg %[job_id]`:让 **被暂停/挂起的后台作业** 在后台 **继续运行**。 > [!example] > ![[_attachment/02-开发笔记/11-Linux/Linux 命令行/Linux-进程相关命令.assets/IMG-Linux-进程相关命令-62B0BBDBE73223C8129C5A55C5F16DC7.png|562]] <br><br> ### nohup 命令——后台运行并忽略挂起信号 `nohup` 命令 **用于运行另一个命令并==忽略所有发给该命令的挂起信号== `SIGHUP`**。(含义:no hang up) **==`nohub` 命令== 搭配 ==后台模式 `&`== 来运行另一个进程,可使其在终端注销或关闭后继续运行,不被 `SIGHUP` 信号终止** ```shell nohub command [args...] & ``` <br> #### `nohup` 下的运行输出 由于 nohup 命令会**解除终端与进程之间的关联**,因此进程的 STDOUT、STDERR 不再同终端绑定。 **`nohup` 会自动将所运行进程的 STDOUT 和 STDERR 消息==重定向==到名为 `nohup.out` 的文件中。** (通常在当前工作目录创建,否则会在 `$HOME` 目录创建) > [!caution] 当使用 nohop 运行另一个进程时,后者的输出会被 **==追加==到已有的 `nohup.out` 文件中**。 > > ![[_attachment/02-开发笔记/11-Linux/Linux 命令行/Linux-进程相关命令.assets/IMG-Linux-进程相关命令-D76DC12EB35A7986D78AE6250C537414.png|604]] > > 当运行位于同一目录中的多个进程时,务必当心,因为**所有的命令输出都会发送到同一个 `nohup.out` 文件中**。 > [!tip] 建议每次使用 `nohup` 时 **==手动指定输出重定向==**,例如: > > ```shell > nohup ./script.sh > output.log 2>&1 & > # 等价于 > nohup ./script.sh &> output.log & > ``` > <br><br> ### screen 工具——会话管理 > Ubuntu 上默认没有安装 screen。 screen 是一个会话管理工具,允许 **在一个单独的 shell 会话** 中管理多个终端窗口,并能在需要时从这些窗口中**分离和重新连接**。 例如,可在远程连接中启动 `screen` 会话,运行程序或任务,然后断开连接,之后再重新连接到同一个会话,而在断开期间,程序继续运行。 screen 功能: - **会话管理**:在一个 shell 终端中可创建**多个 screen 会话**,每个会话有独立的屏幕空间,**可在不同会话间切换** - **会话持久性**:可以断开与 `screen` 会话的连接,**会话中运行的程序会继续运行在后台执行**,此后可以重新连接到该会话。 - **窗口管理**:**在一个 `screen` 会话中可以创建多个窗口**,每个窗口也占有独立的屏幕,可以运行不同的命令或程序,提供了多任务处理的能力。 > [!note] `screen` 会话管理 > > > > ![[_attachment/02-开发笔记/11-Linux/Linux 命令行/Linux-进程相关命令.assets/IMG-Linux-进程相关命令-5A14339C8B08A913ECA03FF17E6AB9DE.png|569]] > [!NOTE] `screen` 窗口管理 > > ![[_attachment/02-开发笔记/11-Linux/Linux 命令行/Linux-进程相关命令.assets/IMG-Linux-进程相关命令-194E34381B2F720F9C71053568DFB3A8.png]] > #### 会话管理相关命令 ```shell # 创建会话 screen # 创建会话并指定一个会话名 screen -S <screen_name> # 进入/恢复会话 screen -r <screen_name> # 列出会话列表, 即显示所有会话 screen -ls # 删除会话 screen -X -S <screen_name> ``` - `Ctrl+D`:**删除** 当前 screen 会话 - `Ctrl+A + D`:**退出** 当前 screen 会话(当前 screen 会话将在后台继续运行) > [!NOTE] 检查当前是否位于 screen 会话中 > > - 查看 `STY` 环境变量:如果环境变量 `$STY` 非空,则意味着可能在一个 screen 会话中 > > ![[_attachment/02-开发笔记/11-Linux/Linux 命令行/Linux-进程相关命令.assets/IMG-Linux-进程相关命令-0D0B229838745669F557DCD6981491F8.png|402]] > > - 查看 `TERM` 环境变量:screen 会话的 `TERM` 变量通常设置为 `screen` 或类似的值。 > > ![[_attachment/02-开发笔记/11-Linux/Linux 命令行/Linux-进程相关命令.assets/IMG-Linux-进程相关命令-4742F41698597086D92FECEF58F8419D.png|390]] > > - 检查当前 shell 的父进程:使用 `ps -p $PPID` 命令 > > ![[_attachment/02-开发笔记/11-Linux/Linux 命令行/Linux-进程相关命令.assets/IMG-Linux-进程相关命令-5BFB7B59EDCA2009F600539B38C7E4D1.png|371]] > <br><br> # 实时显示进程资源占用情况——top 命令 ⭐ > top 命令用于实时查看**系统资源占用情况**,包括 CPU、内存、进程状态等。 `top` 命令: - `-p <pid[,pid...]>`:只查看指定进程的信息 - `-u <user>`:只查看指定用户的进程 - `-d <秒>`: 设置**刷新间隔**(默认为 3 秒) - `-n <次数>`:完成**指定刷新次数**后退出 - `-H`:以 "**线程视图**" 打开(默认是进程视图) - `-c`:显示**进程启动的完整命令行**(默认只显示程序名) > [!example] `top -H` 线程视图 > ![[_attachment/02-开发笔记/11-Linux/Linux 命令行/Linux-进程相关命令.assets/IMG-Linux-进程相关命令-10D517E738B54D188B93B5A6DC0387A2.png|540]] > > `top -H -p <pid>` :查看指定进程中**各个线程**的资源占用情况 > > ![[_attachment/02-开发笔记/11-Linux/Linux 命令行/Linux-进程相关命令.assets/IMG-Linux-进程相关命令-59C19D6EBA5A1DDD7B93DBAE4DE55CB6.png|591]] > > `top -H -p <pid>,<pid>`:查看多个进程的情况: > > ![[_attachment/02-开发笔记/11-Linux/Linux 命令行/Linux-进程相关命令.assets/IMG-Linux-进程相关命令-CDF7A20AB91C27738AEEDC2071FD9801.png|517]] > <br> ## top 字段说明 示例: ![[_attachment/02-开发笔记/11-Linux/Linux 命令行/Linux-进程相关命令.assets/IMG-Linux-进程相关命令-FD219BE2A32045EF00CD7B8803ACDD30.png|670]] #### (1)顶部系统信息 ###### 第一行 top:系统运行状态 | | 字段 1 | 字段 2 | 字段 3 | 字段 4 | | --- | -------- | ------------------- | ------------- | ---------------------------- | | 含义 | 当前系统时间 | 系统自启动以来已运行时间 <br> | 当前**登录的用户数量** | **系统负载**(1 分钟、5 分钟、15 分钟平均值) | | 示例 | 19:21:08 | **up** 1 day, 14:43 | 4 users | load average: 0.09,0.23,0.26 | > [!info] Load Average 值的含义 > > load average 值:过去 **1/5/15 分钟内** 处于 **==Runnable 状态==的任务数** 的指数加权移动平均值(**EWMA**)。 > > - 值范围是 $[0, ∞)$,没有明确上界; > - Linux 系统 **==每 5 秒==** 记录一次 "**正处于 ==Runnable 状态==的任务数量**”,然后更新**时间窗口内**(1/5/15 分钟)的 EWMA **移动平均值**。 > - 例如过去 1 分钟内,一半时间内**只运行着一个任务**,另一半时间系统完全空闲,则 load average: 0.5。 > - "**任务**" 是指调度单位,可等价理解为 "**线程**"。 > - **只计入 ==Runnable 状态==的任务数**,其它休眠、暂停、僵尸进程都不计入。 > > 简单来说,其值反映过去 1/5/15 分钟内,**==需要使用 CPU 的平均任务总数==**(也即 **CPU 调度队列的平均长度**,包括正在占用 CPU 的 + 处于就绪状态正等待调度的任务总数) > > 以 4 核 CPU 为例,`load average: 8.0` 意味着近 1 分钟内 **平均有 8 个任务在争抢 CPU**,而 CPU 共 4 核,故此时系统已过载。 ###### 第二行 Tasks:进程统计 | | totaol | running | sleeping | stopped | zombie | | --- | ------------- | --------------------- | -------- | ------- | ------ | | 含义 | 系统中**当前进程总数** | **正在运行的进程总数**(占用 CPU) | 休眠进程总数 | 暂停进程总数 | 僵尸进程总数 | ###### 第三行 %Cpu(s):CPU 使用情况(所有核心的平均值) | 字段 | 解释 | 含义 | | --- | -------------- | --------------------------------------------------------------------- | | us | UserMode | **用户态**占用 CPU 百分比(执行普通程序) | | sy | SystemMode | **内核态**占用 CPU 百分比(执行系统调用) | | ni | | **用户进程**中被设置 nice 值的进程占用百分比 | | id | idlle time | **CPU 空闲时间百分比** | | wa | wait I/O | CPU 处于 "**空闲状态**" 且系统中**有进程因为等待 I/O 而阻塞**,该状态下 CPU 空闲时间占 CPU 总时间的百分比。 | | hi | hard interrupt | 处理 **硬件中断** 占用的 CPU时间百分比 | | si | soft interrupt | 处理 **软件中断** 占用的 CPU时间百分比 | | st | Steal time | 当前 “**虚拟机**“ 被 “**宿主机**” 偷走 CPU的时间(物理机上运行的系统则恒为 0) | ###### 第四行 Mib Mem:物理内存(RAM)使用情况 | | total | free | used | buff/cache | | --- | --------- | -------- | ----------- | ----------------------------- | | 含义 | 总内存容量(MB) | 空闲内存(MB) | 已用内存(不包括缓存) | **buffer 或 page cache 占用**的内存 | ###### 第五行 MiB Swap:交换分区(Swap)使用情况 | | total | free | used | avail Mem | | --- | ----------- | ----------------- | --------- | ---------------------------- | | 含义 | 总交换分区大小(MB) | 剩余可用的 swap 空间(MB) | 当前已用 swap | 可用内存(包括可被回收的内存,如 page cache) | #### (2)进程列表部分 | 字段 | 说明 | | ------- | ---------------------------------------------------------------------- | | PR | 进程优先级(Priotity),**值越小,优先级越高** | | NI | nice 值,**负数表示高优先级**,正数表示低优先级,范围:-20 ~ 19 | | VIPT | **虚拟内存使用量**(Virtual Memory)——**进程申请的所有内存**,包括未实际使用的、共享库占用的等 | | RES | **实际占用的物理内存**(Resident Memory)。不包括交换分区,不包括共享库未修改部分 | | SHR | **共享内存大小**(和其他进程共享的内存,如共享库) | | S | **进程状态**(`R`=运行中,`S`=可中断休眠,`D`=不可中断休眠,`Z`=僵尸,`T`=暂停或被调试) | | %CPU | 进程当前 **使用的 CPU 百分比**(相对于一个核心);例如,若值为 300% 说明使用了三个核心 | | %MEM | 进程当前 **占用的物理内存百分比** | | TIME+ | **累计占用的 CPU 时间**,格式为 `MM:SS.hh` (`分钟:秒.百分秒`),例如 `0:03.45` 表示占用 3.45 秒 | | COMMAND | 启动该进程的命令或可执行文件名 | > [!info] 注:VIPT = RES + SWAP + 映射文件 + 保留的未分配空间 > [!NOTE] PR 和 NI 的关系(进程调度优先级) > > Linux 中,调度优先级 **PR = 基础优先级 + NI**。 > 其中,NI 值可通过 `nice` 和 `renice` 命令调整。 <br> ## top 交互界面快捷键 | 按键 | 说明 | | -------- | ----------------------------------------------------------------------- | | `q`(小写) | 退出 top 界面 | | `h` | 交互界面帮助信息 | | | | | `H` | 切换 **线程/进程视图** | | 1 | 显示/隐藏 **每个 CPU 核心**的具体使用率 | | `d` | **修改刷新时间**(默认 3 秒) | | `t` | 切换 **CPU 使用率**的显示方式(共三种) | | `m` | 切换 **内存使用率** 的显示方式 | | `E`/ `e` | 切换 **顶部栏/任务列表** 中 "**内存使用**" 的 "**单位**"(默认MiB,可切换为 GiB、TiB、PiB、EiB、KiB) | | `c`(小写) | 显示/隐藏 **进程运行的完整命令行** | | | | | `u` | 只显示**指定用户的进程** | | `L` | 按**字符串**筛选 | | `=` | **清除所有筛选条件** | | | | | `x` | 高亮 **当前排序列** | | `b` | `x` 列的高亮模式:**加粗** or **背景高亮** | | | | | `P` | 按 "**CPU 使用率**" 排序(默认,即 %CPU 字段) | | `M` | 按 "**内存使用率**" 排序 | | `T` | 按 "**CPU 时间**" 排序(即 TIME+字段) | | | | | `k`(小写) | **向进程发送信号** | | `r`(小写) | 修改进程的 nice 值 | > [!NOTE] 交互界面下 `h` 显示的帮助信息: > ![[_attachment/02-开发笔记/11-Linux/Linux 命令行/Linux-进程相关命令.assets/IMG-Linux-进程相关命令-501F47A47FBF5A418E78424DCBC10F64.png|546]] > [!NOTE] `t` 切换 CPU 使用率显示方式(三种 + 不显示) > ![[_attachment/02-开发笔记/11-Linux/Linux 命令行/Linux-进程相关命令.assets/IMG-Linux-进程相关命令-FAC1277C0C9CDA3A120FED49D8483E12.png|637]] > [!NOTE] `E` / `e` 切换 **顶部栏/任务列表** 中 "**内存使用**" 的 "**单位**" > ![[_attachment/02-开发笔记/11-Linux/Linux 命令行/Linux-进程相关命令.assets/IMG-Linux-进程相关命令-AD686F8E9CE1A54FD15C375958DB919F.png|502]] <br><br> # 查看所有进程信息——ps 命令 ⭐ `ps` :默认显示 **==当前用户==的**、**从==当前终端==中启动的进程**(all "your" process started from the current terminal) BSD 风格选项: - `a`:显示 ==**所有用户== 的 ==有控制终端== 的进程**(即前台交互式进程) => All process with terminal. Lift the BSD-style "**only yourself**" restriction. - `x`:显示 **==当前用户== 的 ==所有进程==**(即包括无控制终端的 **守护进程、后台进程** ) => Lift the BSD-style "**must have a tty**" restriction. - `u`:显示 **详细信息**(user-orentied format),包括 USER、==%CPU==、==%MEM==、VSZ、RSS、==STAT== 字段 System V 风格选项: - `-e|-A`: 显示**系统中所有进程** - `-f`:**全格式**显示(full-format),包含 UID、PPID,且 CMD 列显示**完整命令行**,还包括 **CPU 利用率(C)**、**进程启动时间(STIME)** - `-l`:**长格式**显示(long-format),包含**进程状态、进程优先级**等信息 - `-o`:**自定义显示字段**,例如 `-o pid,ppid,user,stat,%cpu,%mem,cmd` - `-p <pid...>`:查看指定进程(可省略`-p`,**==直接跟 `pid`==**,例如 `ps [pid]`) - `--ppid <ppid>`:按**父进程**筛选 - `-u <user>`:按指定的 "**有效用户**" 进行筛选(effective UID,==EUID==) - `-U <user>`:按指定的 "**真实用户**" 进程筛选(real UID,==RUID==) - `-C <command>`:按**进程启动命令**筛选 - `--sort=[-]<col>`:**指定排序的列**(列名前带 `-` 表示**降序排列**) - `-y`:仅搭配`-l` 使用,不显示 FLAGS 字段,显示 RSS 字段来代替 ADDR 字段。 - `-H`:显示**进程树结构** - `--forest` 使用 ASCII 字符**绘制进程的层级信息** => 直观追踪父子进程 > [!quote] > > By default, `ps` selects all processes **with the same effective user ID (euid=EUID) as the current user** and **associated with the same terminal as the invoker**. > For example, if you **open a gnome-terminal and give the ps command**, it will list **all your processes started from that terminal**. [^1] > [!NOTE] 关于 EUID 与 RUID > > - **EUID(Effective UID,==有效用户==)**:该进程运行时 **享有其权限的用户**,决定了进程访问权限 > - 例如, `sudo` 启动进程,则**进程的有效用户是 root**。 > - EUID 可以在进程运行期间改变,通过使用 `setuid`、`seteuid` 等系统调用来改变进程的权限。 > - **RUDI(Real UID,==真实用户==)**:启动这个进程的 "**实际用户**",是谁运行的这个程序 > - 例如,执行 `sudo` 前的用户是 yht。 > > **ps 中各选项下显示的 USER 或 UID,均为 ==EUID==**,若要**查看 RUID**,可使用 `ps -o ruid` 指定显示该字段。 > [!NOTE] `ps` 的命令选项风格 > > ps 命令的选项有**三种风格**(由于历史原因),输出信息略有不同, > > | | 说明 | 示例 | > | --------------- | --------------------------- | ------------- | > | **BSD 风格** | 无中划线,例如 `a`、`u`、`x` | `ps aux` | > | **System V 风格** | 以中划线 `-` 起始,例如 `-e`,`-f`; | `ps -ef` | > | GNU 长选项 | 双中划线,例如 `--forest`、`--sort` | `ps --forest` | > <br> ### 使用示例 ```shell # 查看系统中所有进程 ps aux ps -el # 查看指定进程(可多个) ps [options] [-p|--pid] pid[,pid] ps u [pid] # 长格式查看指定进程 # 查看当前进程的父进程 ps -p $PPID # 显示CPU占用率前10的进程 ps aux --sort=-%cpu | head -n 10 ``` ## 字段说明 > [!note] 不同选项下显示的字段 > ![[_attachment/02-开发笔记/11-Linux/Linux 命令行/Linux-进程相关命令.assets/IMG-Linux-进程相关命令-50A9D23AAEF4A4A9F816EEA44951579F.png|606]] | 所属选项 | 字段 | 含义 | | ---------------------- | --------- | ----------------------------- | | `ps` 基本字段 ↓→ | TTY | 控制终端 | | | TIME | 进程使用的 **CPU 时间总和** | | | CMD | 进程简略命令行 | | | | | | BSD 风格 `u` 选项 ↓→ | USER | **EUID,有效用户 ID** | | | %CPU、%MEM | CPU、物理内存占用百分比 | | | VSZ | 虚拟内存使用(KB) | | | RSS | 实际物理内存使用(KB) | | | STAT | 进程状态 | | | START | 进程启动时间 | | | COMMAND | 进程完整命令行 | | | | | | System V 风格 `-f` 选项 ↓→ | UID | **EUID,有效用户 ID** | | | C | CPU 使用率 | | | STIME | 进程启动时间 | | | PPID | 父进程 ID | | | | | | System V 风格`-l` ↓→ | F | 进程标志位 | | | S | 进程状态(仅显示主状态码) | | | PRI | 动态优先级(越小越优先) | | | NI | nice 值 | | | ADDR | 进程在内核中的地址(已废弃或无意义,通常显示为 `-`) | | | SZ | **虚拟内存页数** | | | WCHAN | 正在等待的内核函数(如果 S 字段是 S 或 D 休眠时) | ### 关于 `CMD` 和 `COMMAND` 字段的内容差异 ![[_attachment/02-开发笔记/11-Linux/Linux 命令行/Linux-进程相关命令.assets/IMG-Linux-进程相关命令-13EC3EBE21A7D551F6B449D983CDF007.png|656]] `CMD` 和 `COMMAND` 两个字段在不同选项下,具体显示的内容略有不同[^2]: - `COMMAND` 的内容是 "full command line with arguments"; - `CMD` 的内容有两种可能情况: - `ps` 显示 "executable name/process accounting name",即 ==`ucmd`==,**可执行文件名**,**不可改**(the "**command**" format specifier) - `ps -f` 指令显示 "reconstructed / full command line with arguments",即 ==`args`==,**可被修改** (the "**args**" format specifier) > [!quote] > ![image-20230921234949181](_attachment/02-开发笔记/11-Linux/Linux%20命令行/Linux-进程相关命令.assets/IMG-Linux-进程相关命令-C4903850589861A87B7E105BA54DA13A.png) > > - `ps` uses the **default format**, which shows the pid, terminal, cumulated CPU time, and the **==executable name==** (`ucmd`). > - The **executable name is not modifiable,** and reflects exactly **the name of the executable used**. > > - `ps -f` uses the full format, which among other fields, shows the **full command with arguments** (`command`, or `args`). > - The **full command is modifiable**。 > > `ps` and `ps -f` display different things for CMD: the executable name (`ps`, the "command" format specifier) and the reconstructed command line (`ps -f`, the "args" format specifier). The latter uses the process's ARGV and sees changes to it, while the executable name itself is unchanged. <br> ### 进程 STAT 状态码 ###### 主状态码 | 状态码 | 说明 | 触发场景 | | --- | --------------------------------------------------------------------- | ----------------------------------- | | R | 正在运行(Running/Runnable)——可能正占有 CPU,也可能**在调度队列等待调度**。 | | | S | **可中断休眠**(Interruptible Sleeping) | 调用 `sleep()`、等待 socket I/O、等待信号量时; | | D | **不可中断休眠**(Uninterruptible Sleeping) | 等待磁盘 I/O | | T | **暂停**(Stoped)——收到**暂停信号(19 or 20)**而暂停,仅当收到 **SIGCONT(18) 信号**才会恢复执行 | 收到信号 SIGSTOP(19) 或 SIGTSTP(20) | | t | **被附加调试**而暂停(traced) | 例如被 `gdb -p` 附加调试 | | Z | 僵尸进程(Zombile) | 子进程结束但父进程未调用 `wait` 或 `waitpid` 回收 | | X | Dead,已死进程(用户空间极少见,通常是内核回收标记时使用) | | ###### 状态修饰符 <br><br> # 系统调用相关——strace `$ strace <ELF_file>` 追踪程序代码中使用的系统调用 %% # 协程相关 > `coproc` 是 `bash` 中的关键字,而非独立的`Linux` 命令,所以 `man` 手册中查无此命令。 `$ coproc` :**在后台**创建一个 **子 shell** 并**在子 shell 中执行指定命令**,同时与该子 shell **建立一个双向通信的管道**。 当在bash脚本或交互式bash会话中使用`coproc`,**bash 会为子进程的标准输入和标准输出创建管道**,并为这些文件描述符分配一个**数组**名,使你可以在主进程中读取或写入这些文件。 - `coproc` 会将进程名称默认设置为`COPROC`。只有在拥有多个协程时才需要对协程进行命名,因为要和它们进行通信,需要进行区分。 ```shell # 自定义协程的进程名字. # 左花括号之后, 右花括号之前必须有一个空格。内部命令必须以分号`;`结尾。 coproc My_Job { sleep 10; } # 示例: # 使用coproc启动一个简单的bc进程(计算器工具) coproc CALC { bc; } # 向bc进程发送一个计算表达式 echo "5 + 5" >&"${CALC[1]}" # 读取bc进程的输出 read -r result <&"${CALC[0]}" echo "The result is: $result" # 关闭文件描述符 exec {CALC[0]}>&- exec {CALC[1]}>&- ``` > ![image-20231101174003803|693](_attachment/02-开发笔记/11-Linux/Linux%20命令行/Linux-进程相关命令.assets/IMG-Linux-进程相关命令-08092AEF4F6A4201FF3D57A28B0D8147.png) %% <br><br><br> # 参考资料 # Footnotes [^1]: [What is the difference between ps and ps -e command in linux](https://stackoverflow.com/questions/29179251/what-is-the-difference-between-ps-and-ps-e-command-in-linux) [^2]: [Why does the following two commands of ps give different \`CMD\` field? - Unix & Linux Stack Exchange](https://unix.stackexchange.com/questions/492312/why-does-the-following-two-commands-of-ps-give-different-cmd-field)