SerenityOS `uptime` 命令详解:从 man 手册到内核时钟的完整链路
2026/9/10 9:41:47 网站建设 项目流程

SerenityOSuptime命令详解:从 man 手册到内核时钟的完整链路

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

uptime是 SerenityOS 中一条用于查询系统已运行时间的标准命令行工具,其行为由 Base/usr/share/man/man1/uptime.md 这份 man 手册定义。本文以该手册为核心,结合 Userland/Utilities/uptime.cpp、Kernel/FileSystem/SysFS/Subsystems/Kernel/Uptime.cpp 与 AK/NumberFormat.cpp 等源码,讲清它的用法、输出格式与底层数据来源,帮助你既能直接上手使用,也能理解"一条命令"背后从用户态到内核态的完整实现链路。

命令概述

uptime在 SerenityOS 的 Shell 中直接输入即可运行,其作用是:以单行文本形式向 STDOUT 输出系统的运行状态信息,包括系统上线时间与已持续运行时长

$ uptime 2024-01-24 06:23:27 up 4:20:00

默认输出分为两个部分:

  • 前半段2024-01-24 06:23:27:当前系统时间(日期 + 时分秒);
  • 后半段up 4:20:00:系统自启动以来已运行的时长,采用H:MM:SS的"数字时钟"格式(小时不足两位时省略前导零,如4:20:00)。

与 Linux/BSD 的uptime不同,SerenityOS 的默认输出末尾还会追加当前登录用户数(详见下文"登录用户统计"一节)。手册中标注的FIXME(见 Userland/Utilities/uptime.cpp)也提示:为了对齐 Linux 与 BSD,未来还计划输出系统负载均值(load averages),但当前内核尚未提供该数据。

命令行选项

uptime支持两个选项,均由 LibCore/ArgsParser.h 解析,定义于源码 Userland/Utilities/uptime.cpp:

短选项长选项功能
-p--pretty仅输出运行时长,使用人类可读的自然语言格式
-s--since仅输出系统上线的时间点,格式为yyyy-mm-dd HH:MM:SS

两个选项的源码行为(Userland/Utilities/uptime.cpp):

  • -s生效时:用"当前时间戳减去运行秒数"反推出系统上线时刻,再通过 LibCore/DateTime 格式化为日期时间字符串;
  • -p生效时:调用human_readable_time()输出自然语言时长;
  • 两者均未指定时:输出默认格式(当前时间 + 数字时钟时长 + 用户数)。

注意:-p-s同时给出时,-s分支优先(源码中先判断output_since),-p会被忽略;二者互斥逻辑并未在参数解析层强制,属于使用时需留意的细节。

示例演示

默认输出

$ uptime 2024-01-24 06:23:27 up 4:20:00

人类可读格式(-p

$ uptime -p Up 2 minutes, 20 seconds

系统上线时间(-s

$ uptime -s 2024-01-24 06:23:27

输出格式的源码实现

人类可读时长:human_readable_time()

-p使用的human_readable_time()定义于 AK/NumberFormat.cpp,其逻辑为:依次以 86400、3600、60 为除数分解出天数、小时、分钟、剩余秒数,再按"非零才输出 + 单复数后缀(day/days)"的规则拼接,例如:

  • 140秒 →Up 2 minutes, 20 seconds
  • 90061秒 →1 day 1 hour 1 minute 1 second

一个值得注意的边界处理:若天、时、分均为 0,则即使秒数为 0 也会输出0 seconds,保证输出永不空白。

数字时钟格式:human_readable_digital_time()

默认输出末尾的4:20:00由 AK/NumberFormat.cpp 的human_readable_digital_time()生成:小时、分钟、秒分别以{:02}补零(小时为 0 时省略),最终形如H:MM:SS

登录用户统计

默认模式(无选项)下,uptime会读取/var/run/utmp(一个 JSON 文件),以该文件对象中的条目数作为登录用户数,并根据数量输出单复数:

2024-01-24 06:23:27 up 4:20:00, 1 user 2024-01-24 06:23:27 up 4:20:00, 3 users

该 JSON 文件由 Userland/Utilities/utmpupdate.cpp 维护——系统会话在登录/注销时通过utmpupdate -c/-d增删条目(详见utmpupdate的 man 手册 Base/usr/share/man/man1/utmpupdate.md)。同一机制也被 Userland/Utilities/w.cpp 的w命令复用。

底层原理:数据从内核到用户态

数据源头:SysFS 中的/sys/kernel/uptime

uptime的运行秒数并非自己计时,而是读取 SysFS 虚拟文件/sys/kernel/uptime(源码见 Userland/Utilities/uptime.cpp)。该文件由内核的 SysFS 子系统实时生成,实现位于 Kernel/FileSystem/SysFS/Subsystems/Kernel/Uptime.cpp:

ErrorOr<void> SysFSUptime::try_generate(KBufferBuilder& builder) { return builder.appendff("{}\n", TimeManagement::the().uptime_ms() / 1000); }

即每次读取时,内核都会把TimeManagement维护的毫秒级运行时长(uptime_ms(),见 Kernel/Time/TimeManagement.cpp)除以 1000 后写出——因此uptime拿到的是自系统启动以来的总秒数,字符串转整数由AK::StringUtils::convert_to_uint()完成。

沙箱化访问:pledge 与 unveil

uptime启动后立即声明最小权限(Userland/Utilities/uptime.cpp):

  • pledge("stdio rpath"):只保留标准 I/O 与只读路径访问能力;
  • unveil("/sys/kernel/uptime", "r")unveil("/var/run/utmp", "r"):把可访问的文件系统路径收敛到仅这两个只读文件,随后unveil(nullptr, nullptr)锁定。

这体现了 SerenityOS 用户态工具"默认最小权限"的典型模式:即使工具被攻破,也几乎无路径可写、无额外文件可读。

时区与时间格式化

-s与默认输出中的时间字符串均通过 LibCore/DateTime 生成。-s分支计算since_timestamp = 当前时间戳 - 运行秒数后再格式化,因此输出的是系统当前时区下的上线时刻。

构建与运行环境

uptime属于 SerenityOS 的用户态基础工具集,随系统镜像一同编译,构建注册见 Userland/Utilities/CMakeLists.txt。使用前提:

  • 它依赖内核 SysFS(/sys/kernel/uptime)与/var/run/utmp,因此只能在 SerenityOS 系统内运行,不能直接移植到普通 Linux 主机;
  • 在 SerenityOS 的 Shell 中直接执行即可,无需额外安装或配置;
  • 由于没有参数时依赖utmp文件中的会话条目,-p/-s两种"仅读内核时钟"的模式在无登录会话的环境中也能正常工作。

小结

  • uptime默认输出"当前时间 + 运行时长(H:MM:SS)+ 登录用户数";
  • -p输出自然语言时长,-s输出系统上线时刻;
  • 运行秒数来自内核 SysFS 节点/sys/kernel/uptime,用户数来自/var/run/utmp
  • 工具通过pledge/unveil以最小权限运行,时长格式化由 AK 的human_readable_time/human_readable_digital_time完成。

手册原文位于 Base/usr/share/man/man1/uptime.md,源码位于 Userland/Utilities/uptime.cpp,感兴趣的读者可沿着这两处继续深入。

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

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

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

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

立即咨询