news 2026/9/10 13:32:16

SerenityOS `w` 命令完全指南:查看当前登录用户与终端活动状态

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
SerenityOS `w` 命令完全指南:查看当前登录用户与终端活动状态

SerenityOSw命令完全指南:查看当前登录用户与终端活动状态

【免费下载链接】serenityThe Serenity Operating System 🐞项目地址: https://gitcode.com/GitHub_Trending/se/serenity

导读

w是 SerenityOS 系统中用于查看当前已登录用户及其终端活动状态的系统工具,其作用与类 Unix 系统中的同名命令一致。本文以 Base/usr/share/man/man1/w.md 手册页为骨架,结合其实现源码 Userland/Utilities/w.cpp、登录会话记录工具utmpupdate以及终端应用 Userland/Applications/Terminal/main.cpp 的调用链,带你完整掌握w的用法、输出字段含义、底层数据来源(/var/run/utmp/sys/kernel/processes),以及它与其他用户管理命令(whoamiusermodutmpupdate)之间的关系。读完本文,你将能够熟练使用w排查多用户登录状态、定位空闲会话,并理解 SerenityOS 中登录会话记录机制的完整数据流。

命令概览

w命令显示关于当前登录用户的信息,包括每个登录会话对应的终端(TTY)、登录时间、空闲时长以及当前正在前台运行的命令。其基本形态如下:

$ w [--no-header] [user]
  • user:可选位置参数。指定后,w只显示该指定用户的登录会话信息。
  • -h,--no-header:可选开关。指定后不显示表头行(USER TTY LOGIN@ IDLE WHAT)。

关于命令的完整选项与参数说明,可以直接查阅仓库内手册 Base/usr/share/man/man1/w.md。

参数解析的实现

w使用 SerenityOS 自带的Core::ArgsParser完成参数解析,对应源码位于 Userland/Utilities/w.cpp:

bool hide_header = false; StringView username_to_filter_by; Core::ArgsParser args_parser; args_parser.add_option(hide_header, "Don't show the header", "no-header", 'h'); args_parser.add_positional_argument(username_to_filter_by, "Only show information about the specified user", "user", Core::ArgsParser::Required::No); args_parser.parse(args);

可以看到:

  • -h/--no-headerhide_header布尔变量绑定,决定是否输出表头;
  • user可选位置参数(Required::No),与username_to_filter_by绑定,用于按用户名过滤输出。

输出格式详解

w默认输出一个表头加若干数据行,每个登录会话一行。表头与数据行的格式由源码中的两处格式化字符串决定(Userland/Utilities/w.cpp 与 Userland/Utilities/w.cpp):

USER TTY LOGIN@ IDLE WHAT
列名含义生成方式(源码依据)
USER登录用户名由会话记录中的uid通过/etc/passwd反查得到;若反查失败则直接显示数字 UID
TTY伪终端名根据 TTY 设备的主设备号映射为pts:Ntty:N
LOGIN@登录时刻由会话记录中的login_at时间戳按%b%d %H:%M:%S格式化(如Sep09 04:11:23
IDLE空闲时长当前时间减去 TTY 设备文件的st_mtime(最后一次活动时间),以秒为单位显示
WHAT当前前台命令在该 TTY 上运行的、PID 等于其进程组 ID 的进程名;无法获取时显示n/a

一个典型的输出形如:

USER TTY LOGIN@ IDLE WHAT anon pts:0 Sep09 04:05:33 12s Shell root tty:1 Sep09 03:58:01 600s n/a

TTY 名称的映射逻辑

源码中的tty_stat_to_pseudo_name函数(Userland/Utilities/w.cpp)根据 TTY 设备的主设备号把设备路径转换为人类可读的名称:

  • 主设备号201pts:{minor}(伪终端,即终端模拟器使用的会话);
  • 主设备号4tty:{minor}(物理/系统控制台终端);
  • 其他类型返回Unknown TTY device type错误。

空闲时长(IDLE)的计算原理

w通过stat获取 TTY 设备文件的st_mtime(最后修改时间)作为"最后一次终端活动时间",再用当前 Unix 时间戳减去它得到空闲秒数(Userland/Utilities/w.cpp):

auto maybe_stat = Core::System::stat(tty); if (!maybe_stat.is_error()) { auto stat = maybe_stat.release_value(); auto idle_time = now - stat.st_mtime; if (idle_time >= 0) { builder.appendff("{}s", idle_time); idle_string = TRY(builder.to_string()); } }

如果无法对 TTY 执行stat(例如会话记录中的 TTY 已不存在),则IDLEWHAT均显示为n/a

当前前台命令(WHAT)的推断

WHAT列通过进程统计信息反查:遍历 Userland/Libraries/LibCore/ProcessStatisticsReader.h 提供的ProcessStatistics列表,找到tty与当前 TTY 匹配、且pid == pgid(进程 ID 等于进程组 ID,即该进程组的组长)的进程,取其name作为前台命令(Userland/Utilities/w.cpp)。这一"进程组组长即前台进程"的推断方式与常规 Unix 会话模型一致。

按用户过滤

当传入user位置参数时,w只输出该用户的会话行。源码中通过用户名精确字符串比较实现过滤(Userland/Utilities/w.cpp):

if (!username_to_filter_by.is_empty() && username_to_filter_by != username) return {};

例如:

$ w anon

只显示用户anon的所有登录会话;不指定参数则显示所有用户。

底层数据来源:/var/run/utmp/sys/kernel/processes

w的输出并非凭空生成,而是来自两个数据源:

  1. /var/run/utmp:登录会话记录的 JSON 文件。w打开并读取该文件(Userland/Utilities/w.cpp),文件内容是一个 JSON 对象,以 TTY 名为键,每个会话包含uidpidfromlogin_at等字段。若解析失败(非 JSON 对象),w会向标准错误输出Error: Could not parse /var/run/utmp并返回退出码 1。
  2. /sys/kernel/processes:内核导出的进程统计信息。w通过Core::ProcessStatisticsReader::get_all()(Userland/Utilities/w.cpp)读取,用于推断各 TTY 上前台运行的命令(WHAT列)。

安全加固:pledge 与 unveil

w在启动时调用了 SerenityOS 的沙箱原语pledgeunveil(Userland/Utilities/w.cpp),声明自己只需要"标准 I/O + 读路径"权限,并只允许读取以下文件/目录:

  • /dev(TTY 设备,用于stat计算空闲时长)
  • /etc/group/etc/passwd(用户与组信息反查)
  • /etc/timezone(时间相关)
  • /var/run/utmp(登录会话记录)
  • /sys/kernel/processes(进程统计)

这是一种典型的"最小权限"设计:即使w被攻破,也无法写入任何文件或访问未声明的资源。

登录会话从何而来:utmpupdate与终端模拟器的配合

w读取的/var/run/utmp由另一个命令维护:utmpupdate。其用法为:

$ utmpupdate [--create] [--delete] [--PID PID] [--from From] <tty>
选项说明
-c,--create为指定 TTY 创建登录会话记录
-d,--delete删除指定 TTY 的登录会话记录
-p PID,--PID PID记录会话对应的进程 PID
-f From,--from From记录会话来源(如Terminal
tty(位置参数)TTY 名称

utmpupdate的实现位于 Userland/Utilities/utmpupdate.cpp:--create时会以当前调用者 UID、给定 PID 与当前时间构造一条记录写入 JSON;--delete时按 TTY 名移除记录。-c-d互斥,同时指定会报错并返回 1。

Terminal 应用的调用链

SerenityOS 自带的终端模拟器 Terminal 在创建/关闭伪终端会话时,会以子进程方式调用utmpupdate来登记或注销会话(Userland/Applications/Terminal/main.cpp):

Array utmp_update_command { "-f"sv, "Terminal"sv, "-p"sv, pid_string.bytes_as_string_view(), (create ? "-c"sv : "-d"sv), tty, }; auto utmpupdate_pid = TRY(Core::Process::spawn("/bin/utmpupdate"sv, utmp_update_command, {}, Core::Process::KeepAsChild::Yes));

这正是wLOGIN@TTY等字段得以填充的源头。同时,utmpupdate自身也通过pledge("stdio wpath cpath")unveil("/var/run/utmp", "rwc")将权限限制在读写/var/run/utmp(Userland/Utilities/utmpupdate.cpp)。

构建与集成位置

w属于 SerenityOS 用户态核心命令集,被列入REQUIRED_TARGETS(构建系统强制要求的目标),源码条目位于 Userland/Utilities/CMakeLists.txt,并在 Userland/Utilities/CMakeLists.txt 的必需命令列表中。这意味着在任何完整构建的 SerenityOS 镜像中,/bin/w都会随系统一起编译安装。

常见用法示例

# 查看所有登录用户及其终端活动 $ w # 不显示表头,便于脚本解析 $ w --no-header # 只查看指定用户(如 anon)的会话 $ w anon # 组合使用:只看 anon 且不要表头 $ w -h anon

-h与位置参数可以任意组合,顺序不影响解析结果,因为参数均由Core::ArgsParser统一处理。

相关命令

w通常与以下命令配合使用,形成一个完整的"用户与会话管理"工具链:

  • whoami(1):打印当前有效 UID 对应的用户名。示例:whoami输出anon# whoami(root)输出root。它回答的是"我是谁",而w回答的是"现在都有谁登录着、在干什么"。
  • utmpupdate(1):维护/var/run/utmp登录会话记录,是w数据的上游写入者,其手册页也反向链接回w
  • usermod(8):管理系统用户账户(如修改用户所属组、Shell 等),与查看会话状态的w互补。

小结

w虽然是一个"小"命令,但它的实现串起了 SerenityOS 中多条关键机制:JSON 格式的系统状态文件(/var/run/utmp)、内核进程统计接口(/sys/kernel/processes)、pledge/unveil最小权限模型,以及终端模拟器与会话登记工具之间的进程协作。理解w的完整数据流,也就理解了 SerenityOS 多用户会话管理的核心脉络。

【免费下载链接】serenityThe Serenity Operating System 🐞项目地址: https://gitcode.com/GitHub_Trending/se/serenity

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

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/10 13:31:11

C语言单链表+文件操作实现图书馆管理系统

简介&#xff1a;这是一套基于C语言实现的轻量级图书馆管理系统&#xff0c;面向计算机专业初学者与C语言课程设计学生&#xff0c;聚焦链表数据结构应用与控制台交互逻辑训练。系统完整覆盖管理员权限管理、读者信息维护、图书借阅与归还等核心业务流程&#xff0c;采用单链表…

作者头像 李华
网站建设 2026/9/10 13:30:45

OSG Geometry模块详解:3D图形编程核心与实践

1. 项目概述今天我们来深入探讨OSG(OpenSceneGraph)中的Geometry模块&#xff0c;这是3D图形编程中最基础也最核心的部分。Geometry负责定义和绘制各种几何形状&#xff0c;从简单的三角形到复杂的3D模型都离不开它。在实际项目中&#xff0c;几何体绘制直接决定了场景的视觉效…

作者头像 李华
网站建设 2026/9/10 13:29:35

中国城市统计年鉴面板数据处理与应用指南

1. 项目背景与数据价值《中国城市统计年鉴》作为记录我国城市化进程的核心官方资料&#xff0c;其面板数据的系统整理对区域经济研究具有里程碑意义。这个覆盖1985-2024年&#xff08;含2023年预测数据&#xff09;的完整数据集&#xff0c;首次实现了三个关键突破&#xff1a;…

作者头像 李华
网站建设 2026/9/10 13:29:04

电网韧性优化:移动电源车预配置与动态调度技术

1. 项目背景与核心价值去年参与某沿海城市电网抗台风改造项目时&#xff0c;我亲历了因应急电源配置不合理导致的72小时大范围停电事故。这次经历让我深刻认识到&#xff1a;传统配电网"故障后抢修"的被动模式&#xff0c;在面对极端天气时存在致命缺陷。这也正是IEE…

作者头像 李华