ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

WezTerm Lua API 深入解析:`LocalProcessInfo` 进程信息对象与前台进程探测实战

WezTerm Lua API 深入解析:`LocalProcessInfo` 进程信息对象与前台进程探测实战 WezTerm Lua API 深入解析LocalProcessInfo进程信息对象与前台进程探测实战【免费下载链接】weztermA GPU-accelerated cross-platform terminal emulator and multiplexer written by wez and implemented in Rust项目地址: https://gitcode.com/GitHub_Trending/we/weztermLocalProcessInfo是 WezTerm 向 Lua 配置脚本暴露的本地进程信息对象它描述运行在本机上的进程及其子进程树是mux-is-process-stateful事件回调与pane:get_foreground_process_info()方法的返回值类型。本文将以该对象为骨架完整梳理其字段语义、平台限制并深入结合 procinfo 模块源码 与 LocalPane 实现 讲解其底层数据来源最后给出可复制的状态栏与关闭确认实战示例帮助你在自己的 WezTerm 配置中安全、高效地使用进程信息。什么是LocalProcessInfoLocalProcessInfo自 20220101-133340-7edc5b5a 版本起提供表示运行在本地机器上的一个进程。WezTerm 通过它向 Lua 环境传递进程的 PID、父进程 PID、可执行文件路径、命令行参数、工作目录、运行状态以及完整的子进程树。在 Rust 侧该类型定义在 procinfo/src/lib.rs 中并通过wezterm_dynamic的FromDynamic/ToDynamic派生与luahelper::impl_lua_conversion_dynamic!宏转换为 Lua 可读的对象这就是配置脚本中可以直接用点号访问proc.pid、proc.argv等字段的原因。字段一览字段类型说明pid整数进程 IDppid整数父进程 IDname字符串进程的短名称。受平台限制可能不准确或被截断应优先使用executable或argv字段status字符串进程状态取值见下文argv表进程的参数数组executable字符串可执行映像的完整路径可能为空cwd字符串进程当前工作目录可能为空children表以子进程 PID 为键、值为LocalProcessInfo对象的子进程表在源码中name字段的注释明确指出它对应进程的 COMM 名称与可执行映像名不一定相同进程运行时可自行修改例如 Linux 上的setproctitle()且许多系统会将其截断到 15~16 个字符因此文档建议把executable和argv作为更可靠的判断依据。status字段的类型在 Rust 侧为LocalProcessStatus枚举见 procinfo/src/lib.rs映射到 Lua 后的可取值为Idle、Run、Sleep、Stop、Zombie、Tracing、Dead、Wakekill、Waking、Parked、LockBlocked、Unknown。并非所有取值在所有平台上都可用——例如 Linux 内核的R、S、Z、T、t、X/x等状态码会在 procinfo/src/linux.rs 中被映射为上述枚举其他平台则可能只支持其中一部分。children是一棵递归的进程树键为子进程 PID值为描述子进程的LocalProcessInfo对象因此你可以像遍历树一样层层递归访问整棵进程层级。数据来源与平台差异LocalProcessInfo的获取入口是LocalProcessInfo::with_root_pid(pid)它从指定 PID 出发构建整棵进程树。需要明确的是该信息仅对本地 pane 可用多路复用multiplexer远程 pane、通过ssh连接的远程主机均无法获取远程进程信息。各平台实现位于 procinfo crate 的模块文件中Linuxprocinfo/src/linux.rsmacOSprocinfo/src/macos.rsWindowsprocinfo/src/windows.rs从源码结构看Linux 实现完全基于/proc文件系统枚举/proc下所有数值命名的目录得到 PID 列表读取/proc/pid/stat解析进程名、状态、PPID 与启动时钟starttime通过read_link(/proc/pid/exe)获取可执行文件路径procinfo/src/linux.rs通过read_link(/proc/pid/cwd)获取工作目录procinfo/src/linux.rs通过拆分 NUL 字节分隔的/proc/pid/cmdline得到argvprocinfo/src/linux.rs最后按ppid递归拼装出完整的进程树。需要注意的是平台支持范围可执行路径查询executable仅 Linux、macOS、Windows 支持FreeBSD 等其他 Unix 系统目前不支持非 Linux/macOS/Windows 平台with_root_pid、current_working_dir、executable_path三个方法直接返回None见 procinfo/src/lib.rs路径查询可能因 WezTerm 无法控制的各种原因失败如权限、进程退出、/proc 不可用此时字段为空查询进程信息存在一定运行时开销过度使用可能拖慢 WezTerm详见下文缓存机制。核心 API 一pane:get_foreground_process_info()pane:get_foreground_process_info()自 20220624-141144-bd1b7c5d 起提供返回当前 pane 中前台进程对应的LocalProcessInfo对象若无法确定进程则返回nil。前台进程的判定规则该方法的语义在不同平台上有显著差异这是实际使用时最容易踩坑的地方Unix 系统查询的是进程组组长process group leader即终端前台进程组对应的进程Windows不存在进程组的概念因此改为检查最初启动程序的进程树并把最近产生的后代进程视为前台进程。后者的实现可以在 mux/src/localpane.rs 中看到divine_process_list以根进程为起点递归遍历children利用start_time字段比较各进程的相对年龄选出start_time最大的即最近启动的后代作为foreground并将其children清空后缓存。Windows 上还会通过console句柄字段过滤child.console 0时跳过以规避不相关控制台进程的干扰。使用限制仅本地 pane 可用多路复用 pane、ssh远程连接场景下无法获取查询可执行路径仅限 Linux、macOS、Windows查询失败时返回nil脚本必须做好空值处理。实战状态栏显示前台进程官方文档给出的示例将前台进程的 PID 与可执行文件 basename 显示在右侧状态栏local wezterm require wezterm -- 等价于 POSIX basename(3) -- 给定 /foo/bar 返回 bar -- 给定 c:\\foo\\bar 返回 bar function basename(s) return string.gsub(s, (.*[/\\])(.*), %2) end wezterm.on(update-right-status, function(window, pane) local info pane:get_foreground_process_info() if info then window:set_right_status( tostring(info.pid) .. .. basename(info.executable) ) else window:set_right_status end end) return {}basename函数同时兼容 POSIX 的/与 Windows 的\路径分隔符这段配置在 Linux、macOS、Windows 上都能正确工作。由于get_foreground_process_info()可能返回nil必须先判空再使用字段。值得一提的是WezTerm 内部对前台进程信息做了缓存与后台刷新处理在 mux/src/localpane.rs 中CachedLeaderInfo保存了前台进程 PID、可执行路径与工作目录并带有 TTL 过期机制源码注释还提到tcgetpgrp单次可能耗时约 700µs若 10 个标签页都被鼠标扫过仅取 PID 就可能累计 7ms 造成卡顿——这正是缓存存在的意义。因此查询进程信息有运行时开销应避免过度使用的官方提示对应着真实的性能考量。核心 API 二mux-is-process-stateful事件mux-is-process-stateful事件在多路复用层想要判断某个 pane 是否可以无需用户确认直接关闭时触发。事件语义与返回值该事件是同步的回调必须尽快返回以免阻塞多路复用器事件回调会收到一个代表该 pane 对应进程树的LocalProcessInfo对象返回值约定返回值含义true该进程树被视为有状态stateful关闭 pane 前应提示用户false该进程树可以被直接终止无需提示nil使用默认行为依据skip_close_confirmation_for_processes_named配置判定其他任意值或出错等价于返回nilRust 侧的调用点在 mux/src/localpane.rscan_close_without_prompting通过config::lua::emit_sync_callback同步调用 Lua 钩子仅把Boolean和Nil识别为有效返回值其余一律回退到默认逻辑与文档描述完全一致。默认判定逻辑skip_close_confirmation_for_processes_named当事件返回nil或未定义时WezTerm 使用skip_close_confirmation_for_processes_named配置项做判定。该配置自 20210404-112810-b63a949d 起提供列出被认为无状态、可安全关闭的进程名config.skip_close_confirmation_for_processes_named { bash, sh, zsh, fish, tmux, nu, cmd.exe, pwsh.exe, powershell.exe, }关闭 pane 时WezTerm 会检查该 pane 启动的程序所派生的所有进程名如果全部进程名都命中列表则不弹确认框只要存在一个不在列表中的进程就视为有状态并提示确认。默认判定逻辑在 mux/src/localpane.rs 中实现值得注意两个细节它使用的是flatten_to_exe_names()见 procinfo/src/lib.rs即把整棵进程树展开为可执行文件 basename的集合再与配置列表比对出于对 Fig 工具链的兼容比较前会剥离进程名中(figterm)后缀——Fig 的figterm伪终端夹在 shell 与终端之间进程名形如shell (figterm)不剥离会导致判定永远失败。若事件回调抛错WezTerm 会记录错误日志并回退到默认行为mux/src/localpane.rs保证配置异常不会影响关闭功能。实战递归打印进程树官方示例演示了如何用递归函数遍历children字段并缩进输出通过wezterm.log_info记录进程树全貌。该示例不改变任何行为返回nil走默认逻辑但完整展示了对LocalProcessInfo各字段的读取方式local wezterm require wezterm function log_proc(proc, indent) indent indent or wezterm.log_info( indent .. pid .. proc.pid .. , name .. proc.name .. , status .. proc.status ) wezterm.log_info(indent .. argv .. table.concat(proc.argv, )) wezterm.log_info( indent .. executable .. proc.executable .. , cwd .. proc.cwd ) for pid, child in pairs(proc.children) do log_proc(child, indent .. ) end end wezterm.on(mux-is-process-stateful, function(proc) log_proc(proc) -- 使用默认行为 return nil end) return {}对一个zsh启动bash、bash再启动vim foo的场景输出日志形如INFO config::lua lua: pid1913470, namezsh, statusSleep INFO config::lua lua: argv-zsh INFO config::lua lua: executable/usr/bin/zsh, cwd/home/wez INFO config::lua lua: pid1913567, namebash, statusSleep INFO config::lua lua: argvbash INFO config::lua lua: executable/usr/bin/bash, cwd/home/wez INFO config::lua lua: pid1913624, namevim, statusSleep INFO config::lua lua: argvvim foo INFO config::lua lua: executable/usr/bin/vim, cwd/home/wez递归遍历时注意proc.children以 PID 为键pairs的遍历顺序在 Lua 中不保证稳定若需要固定顺序应先对键排序。进阶基于进程信息定制关闭行为把前面两块内容组合起来可以构建一个比skip_close_confirmation_for_processes_named更精细的关闭策略。例如默认对vim、git可能正处在交互式操作中等进程保持提示而对其他无状态进程直接关闭local wezterm require wezterm -- 若进程树中存在需要保护的有状态程序则要求提示 local STATEFUL { vim true, nvim true, emacs true, git true, } local function tree_has_stateful(proc) if STATEFUL[proc.name] or STATEFUL[(proc.executable:match(([^/\\])$) or )] then return true end for _, child in pairs(proc.children) do if tree_has_stateful(child) then return true end end return false end wezterm.on(mux-is-process-stateful, function(proc) if tree_has_stateful(proc) then return true end return false end) return {}这个示例展示了mux-is-process-stateful的核心价值它收到的proc是整棵进程树根节点你拥有比内置默认逻辑更自由的判定空间。同时它也是同步回调递归遍历深进程树时注意控制复杂度避免拖慢多路复用器。总结与常见陷阱LocalProcessInfo是 WezTerm 连接终端 UI 层与操作系统进程层的桥梁掌握它就能在状态栏展示前台程序、按进程内容定制关闭确认策略。使用时的要点可归纳为字段优先级name可能被截断或被setproctitle()篡改关键判定用executable与argv平台边界仅本地 pane 有数据executable路径查询仅限 Linux/macOS/WindowsWindows 的前台进程由进程树中最年轻的后代推断而来与 Unix 的进程组组长语义不同空值处理get_foreground_process_info()返回nil、executable/cwd可能为空脚本需判空性能意识进程查询有运行时开销WezTerm 内部通过 TTL 缓存缓解相关实现见 mux/src/localpane.rs自定义脚本也应避免在热点回调如update-right-status的每次触发中高频重建进程树事件返回值mux-is-process-stateful只认true/false/nil其余值一律回退默认逻辑回调出错会回退默认逻辑因此配置错误不会造成关闭功能失效但请留意错误日志。相关文档可继续阅读 mux-is-process-stateful 事件、pane:get_foreground_process_info() 与 skip_close_confirmation_for_processes_named 配置完整的 Lua API 索引位于 docs/config/lua。【免费下载链接】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),仅供参考
返回列表