wezterm.procinfo.get_info_for_pid() 进程信息查询 API 详解:从 PID 到完整进程树的 Lua 实战指南
2026/9/13 2:47:16 网站建设 项目流程

wezterm.procinfo.get_info_for_pid() 进程信息查询 API 详解:从 PID 到完整进程树的 Lua 实战指南

【免费下载链接】weztermA GPU-accelerated cross-platform terminal emulator and multiplexer written by @wez and implemented in Rust项目地址: https://gitcode.com/GitHub_Trending/we/wezterm

本篇指南围绕 WezTerm 终端模拟器的 Lua APIwezterm.procinfo.get_info_for_pid()展开,讲解如何仅凭一个进程 ID(PID)查询到该进程的完整信息——包括可执行文件路径、命令行参数、工作目录、进程状态以及其全部子进程构成的进程树。读者将掌握该函数的调用方式、返回对象LocalProcessInfo的每一个字段含义,并通过源码理解其在 Linux、macOS、Windows 三大平台上的底层实现原理,从而能在自己的 wezterm.lua 配置中灵活运用进程信息实现高级功能。

函数速览

wezterm.procinfo.get_info_for_pid()是 wezterm.procinfo 模块 提供的能力之一,自版本20220807-113146-c2fee766起可用。它允许从 wezterm 配置的 Lua 脚本中查询本地系统上运行进程的详细信息。

local info = wezterm.procinfo.get_info_for_pid(pid)
  • 参数pid,一个正整数,即要查询的目标进程 ID。
  • 返回值:一个 LocalProcessInfo 对象,其中携带目标进程自身的信息,并通过嵌套结构包含了它的全部子进程;查询失败时返回nil(例如进程已退出、权限不足或平台不支持)。

从 Lua 绑定源码看,该函数在注册时直接透传给底层实现:lua-api-crates/procinfo-funcs/src/lib.rs 中将get_info_for_pid绑定为LocalProcessInfo::with_root_pid(pid),参数类型为u32。同时该模块还暴露了三个同族函数:

函数返回值说明
wezterm.procinfo.pid()数字返回当前进程(wezterm 自身)的 PID,见 pid.md
wezterm.procinfo.get_info_for_pid(pid)LocalProcessInfo / nil返回指定 PID 的进程树信息
wezterm.procinfo.current_working_dir_for_pid(pid)字符串 / nil返回指定 PID 的当前工作目录,见 current_working_dir_for_pid.md
wezterm.procinfo.executable_path_for_pid(pid)字符串 / nil返回指定 PID 的可执行文件路径,见 executable_path_for_pid.md

基础用法与官方示例

最典型的用法是先通过wezterm.procinfo.pid()拿到 wezterm 自身(更准确地说,是当前运行 Lua 脚本的进程)的 PID,再把它传给get_info_for_pid()做查询。官方文档给出了完整返回示例:

> wezterm.procinfo.get_info_for_pid(wezterm.procinfo.pid()) { "argv": [ "/home/wez/wez-personal/wezterm/target/debug/wezterm-gui", ], "children": { 540513: { "argv": [ "-zsh", ], "children": {}, "cwd": "/home/wez", "executable": "/usr/bin/zsh", "name": "zsh", "pid": 540513, "ppid": 540450, "start_time": 232656896, "status": "Sleep", }, }, "cwd": "/home/wez/wez-personal/wezterm", "executable": "/home/wez/wez-personal/wezterm/target/debug/wezterm-gui", "name": "wezterm-gui", "pid": 540450, "ppid": 425276, "start_time": 8671498240, "status": "Run", }

从示例中可以清晰地读出两层结构:根节点是wezterm-gui进程本身(PID 540450),而children中嵌套了它的一个子进程zsh(PID 540513)。这说明返回值不是孤立的单个进程快照,而是一棵以目标 PID 为根、向下递归完整的进程树

LocalProcessInfo 字段全解析

返回对象的类型定义在 docs/config/lua/LocalProcessInfo.md 中有完整说明,其结构体实现在 procinfo/src/lib.rs。两者结合,每个字段含义如下:

字段类型含义与注意事项
pid数字进程 ID
ppid数字父进程 ID
name字符串进程的短名称。平台限制下可能不准确或被截断(许多系统截断到 15~16 个字符),且进程运行时可能被setproctitle()等机制修改,建议优先使用executableargv字段
executable字符串可执行映像的完整路径,某些情况下可能为空字符串
argv字符串数组进程的参数数组。部分系统允许进程在运行时改写 argv 块
cwd字符串进程当前工作目录,无法访问时为空字符串
status字符串进程状态,枚举取值见下表
start_time数字一个系统相关单位的时钟值,用于刻画进程的相对年龄(如 Linux 上为启动以来的 tick 数)
children以子进程 PID 为键、值为嵌套LocalProcessInfo对象的子进程表
console(仅 Windows)数字与进程关联的控制台句柄(Windows 专有字段)

status字段的可取值在源码的LocalProcessStatus枚举中定义:procinfo/src/lib.rs,包括IdleRunSleepStopZombieTracingDeadWakekillWakingParkedLockBlockedUnknown。需要注意的是,并非所有取值在所有平台都可移植——例如WakekillParked等主要来源于 Linux 内核的进程状态,而 Windows 实现中所有进程的状态统一置为Run(见下文源码分析)。

源码级实现原理:三大平台如何采集进程信息

get_info_for_pid的核心实现在procinfocrate 中,按操作系统分别实现了with_root_pidcurrent_working_direxecutable_path。虽然查询入口一致,但三个平台的采集路径差异很大,理解这些差异有助于预判跨平台行为。

Linux:直接解析 /proc 伪文件系统

Linux 实现(procinfo/src/linux.rs)完全基于/proc文件系统:

  1. 枚举全部进程:遍历/proc目录下所有纯数字命名的目录作为 PID 候选,见all_pids()(procinfo/src/linux.rs)。
  2. 读取每个进程的统计信息:解析/proc/<pid>/stat文件,提取进程名、状态码、PPID 以及自系统启动以来的启动 tick 数(starttime),见info_for_pid()(procinfo/src/linux.rs)。
  3. 补充路径与参数/proc/<pid>/exe的符号链接解析出executable/proc/<pid>/cwd的符号链接解析出cwd/proc/<pid>/cmdline按 NUL 字节切分得到argv,见parse_cmdline()(procinfo/src/linux.rs)。
  4. 状态码映射:将/proc/<pid>/stat中的单字母状态码映射到LocalProcessStatus,例如RRunSSleepDIdleZZombieTStoptTracingX/xDead等(procinfo/src/linux.rs)。
  5. 递归建树build_proc()遍历全部进程,找出所有ppid等于当前节点 PID 的子进程,并用visited集合防止环(procinfo/src/linux.rs)。

macOS:proc_pidinfo 与 sysctl 组合

macOS 实现(procinfo/src/macos.rs)走的是系统调用路线:

  • 枚举进程:通过proc_listallpids()一次性列出全部 PID,且预留了 32 个 PID 的缓冲 padding 以应对查询期间新进程频繁产生的情况(procinfo/src/macos.rs)。
  • 基础信息:通过proc_pidinfo(pid, PROC_PIDTBSDINFO, ...)获取 BSD 进程信息块(PID、PPID、pbi_comm 进程名、启动时间、状态),见 procinfo/src/macos.rs。
  • 可执行文件与参数:优先通过sysctlKERN_PROCARGS2查询拿到 argc、可执行路径与完整 argv(procinfo/src/macos.rs),失败时退回proc_pidpath()获取可执行路径。该模块还附带了针对KERN_PROCARGS2缓冲区解析的单元测试(如 procinfo/src/macos.rs),覆盖了 exe_path 与 argv 之间补零、argv 项之间补零、缓冲区末尾补零以及畸形数据等多种边界情况。
  • 工作目录:通过proc_pidinfoPROC_PIDVNODEPATHINFO读取 vnode 路径信息得到cwd(procinfo/src/macos.rs)。

Windows:Toolhelp32 快照 + PEB 内存读取

Windows 实现(procinfo/src/windows.rs)最为复杂:

  • 枚举进程:基于 Toolhelp32 API 的CreateToolhelp32Snapshot+Process32FirstW/NextW拍摄进程快照(procinfo/src/windows.rs)。
  • 打开目标进程OpenProcess需要PROCESS_QUERY_INFORMATION | PROCESS_VM_READ权限;特别地,如果查询目标是 wezterm 自身进程,会直接跳过以避免死锁(procinfo/src/windows.rs)。
  • 可执行路径:通过QueryFullProcessImageNameW获取(procinfo/src/windows.rs)。
  • argv 与 cwd:通过NtQueryInformationProcess拿到 PEB 指针,再ReadProcessMemory读取RTL_USER_PROCESS_PARAMETERS中的命令行(CommandLine)与当前目录(CurrentDirectory.DosPath)结构,最后用CommandLineToArgvW把命令行字符串拆分成 argv 数组(procinfo/src/windows.rs)。实现还区分了 64 位原生进程与 32 位 WOW64 进程(通过ProcessWow64Information判定),分别用不同宽度的结构体解析(procinfo/src/windows.rs),并对读取长度设置了MAX_PATH * 4的防御上限(procinfo/src/windows.rs)。
  • 状态:由于 Windows 无法提供与 Unix 等价的进程状态枚举,所有进程的status一律置为Run(procinfo/src/windows.rs)。

此外,procinfo/src/lib.rs 表明在非 macOS / Linux / Windows 的平台上,with_root_pidcurrent_working_direxecutable_path均直接返回None——即这些函数仅在三大主流桌面平台上有实际实现。

实战:在配置中查询与展示进程信息

结合 wezterm.procinfo.pid() 的幂等查询

wezterm.procinfo.pid()返回当前进程的 PID。在配置加载阶段(此时运行 Lua 的是 wezterm-gui 进程),把它作为get_info_for_pid的入参,就能拿到以 wezterm-gui 为根的完整进程树——上面的官方示例正是这么做的。

与 pane:get_foreground_process_info() 的关系

在 passing-data.md 中,wezterm.procinfo.get_info_for_pid()被归类为"本地进程状态"(Local Process State)类函数,与pane:get_foreground_process_info()并列。两者的区别在于入口不同:后者从某个 Pane 对象出发,返回该 pane 中前台进程的进程树;而前者接受任意 PID,不依赖 pane 上下文。

捕获 nil 返回

由于目标进程可能在任何时刻退出,或查询权限不足,函数可能返回nil。任何访问其字段的代码都应先判空:

local info = wezterm.procinfo.get_info_for_pid(some_pid) if info then -- 此时可安全访问 info.executable、info.cwd、info.children 等字段 return info.cwd else return "unknown" end

遍历进程树

children是递归嵌套结构,可按需深度遍历,例如收集整棵进程树的可执行文件名(源码中的flatten_to_exe_names即提供了类似思路,见 procinfo/src/lib.rs):

local function walk(info, depth) if not info then return end local indent = string.rep(' ', depth) wezterm.log_info(indent .. info.pid .. ' ' .. (info.executable or '')) for _, child in pairs(info.children or {}) do walk(child, depth + 1) end end local me = wezterm.procinfo.get_info_for_pid(wezterm.procinfo.pid()) walk(me, 0)

使用边界与注意事项

结合官方文档与源码,使用该 API 时有以下几点需要特别留意:

  • 仅限本地进程:该函数直接读取操作系统进程表,因此只能查询运行在 wezterm 所在机器上的本地进程。当通过 SSH 连接远程主机或使用 multiplexer 连接时,无法用它窥探远程进程——这正是 passing-data.md 转而推荐 User Vars、OSC 7 等机制的原因。
  • 可能返回 nil:进程已退出、权限不足、平台不支持(非 Linux/macOS/Windows)等场景下都会得到nil
  • name 字段可信度有限:文档明确提示它可能不准确、被截断,应优先使用executableargv
  • Windows 上的特殊性passing-data.md提到这些本地进程函数在 Windows 上"确定正确的前台进程时可能表现不佳";且 Windows 实现的status恒为Runargv/cwd依赖对目标进程 PEB 的内存读取,进程是 32 位还是 64 位会影响解析路径。
  • 性能开销:以 Linux 实现为例,每次调用都会枚举/proc下全部进程并逐一读取多个文件以递归构建子树。若在update-status等高频回调中频繁调用,可能带来可感知的开销,建议缓存结果或降低调用频率。

相关链接

  • wezterm.procinfo 模块总览
  • wezterm.procinfo.pid()
  • wezterm.procinfo.current_working_dir_for_pid()
  • wezterm.procinfo.executable_path_for_pid()
  • LocalProcessInfo 类型文档
  • pane:get_foreground_process_info()
  • 从 pane 向 Lua 传递数据的最佳实践
  • 底层实现:procinfo/src/lib.rs、procinfo/src/linux.rs、procinfo/src/macos.rs、procinfo/src/windows.rs
  • Lua 绑定注册:lua-api-crates/procinfo-funcs/src/lib.rs

【免费下载链接】weztermA GPU-accelerated cross-platform terminal emulator and multiplexer written by @wez and implemented in Rust项目地址: https://gitcode.com/GitHub_Trending/we/wezterm

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询