最可靠的是 who -b,输出 system boot yyyy-mm-dd hh:mm,精度到分钟,兼容性好;uptime -s 最快但仅新系统支持;/proc/uptime 配合 date 可脚本化推算,但需注意时区与时间校正影响。

直接看结论:用 uptime -s 最快得到精确启动时间;用 who -b 最可靠;uptime 默认只显示运行时长,不带日期。
uptime -s 能直接输出启动时间戳,但不是所有系统都支持
较新发行版(如 Ubuntu 20.04+、CentOS 8+、Debian 11+)的 uptime 支持 -s 选项,执行后返回形如 2026-04-05 08:23:17 的完整时间:
uptime -s
不支持该选项的老系统(如 CentOS 6 或某些精简嵌入式环境)会报错 uptime: invalid option -- 's',此时不能 fallback 到其他命令——得换方法。
常见误操作是看到 uptime 输出里有 up 6 days, 12:45 就手动推算时间,但时区、夏令时、系统时间跳变都会导致误差,尤其跨多天时不可靠。
who -b 是最轻量且兼容性最好的启动时间来源
who -b 读取的是 /var/run/utmp,由内核在启动完成时写入,几乎不受用户空间时间服务(如 systemd-timesyncd 或 ntpd)干扰:
who -b
输出固定为 system boot YYYY-MM-DD HH:MM,精度到分钟,不依赖 systemd,也不需要 root 权限。
- 如果输出为空或报错
cannot open /var/run/utmp,说明 utmp 文件损坏或被清理过(比如某些容器镜像或无状态系统会删掉它) - 该时间点 ≈ init 进程启动完成时刻,比内核启动略晚几十毫秒,但对运维已足够准确
- 不适用于无 utmp 支持的最小化系统(如部分 Alpine 容器),此时需退到
/proc/uptime方案
/proc/uptime 配合 date 是脚本化首选,但要注意浮点精度
/proc/uptime 第一列是自启动以来的秒数(浮点型,含小数),是内核维护的原始计时源,最精确:
awk '{print int($1)}' /proc/uptime
用它反推启动时间要结合当前系统时间,推荐写法:
date -d "@$(($(date +%s) - $(awk '{print int($1)}' /proc/uptime)))" "+%Y-%m-%d %H:%M:%S"
注意几个坑:
-
$(date +%s)返回的是本地时区的 Unix 时间戳,而/proc/uptime是纯秒数,所以结果自动适配本地时区,无需额外处理 UTC - 不要用
date -d "$(cat /proc/uptime | awk '{print $1}') seconds ago"—— 浮点秒数传给date可能触发解析错误,尤其小数部分非零时 - 该方法依赖系统时间未被大幅校正过;若期间执行过
date -s或timedatectl set-time,推算结果会偏移
systemctl status 的 Since 行看着方便,但实际是用户空间就绪时间
执行 systemctl status 后,开头的 Since: 行类似:
Since: Sat 2026-04-05 08:23:42 CST; 6 days ago
这个时间点来自 systemd 的 UserspaceTimestamp,表示用户空间初始化完成、第一个服务启动的时刻,通常比内核启动晚 1–3 秒。
它的问题在于:
- 仅限 systemd 系统,SysVinit 或 OpenRC 发行版无此字段
- 如果 systemd 启动失败后 fallback 到 rescue mode,
Since:可能反映的是救援模式启动时间,而非真正开机时间 - 输出格式受 locale 影响,
grep "Since:"在中文系统可能匹配不到(因显示为“自:”),稳妥做法是systemctl show --property=UserspaceTimestamp --value
真正关键的差异点在于:内核启动完成、init 进程运行、用户空间服务就绪,这三个时间点本身就有毫秒级到秒级的间隔。日常查“什么时候开的机”,用 who -b 就够了;做性能分析或故障定界,才需要拆解这三者。











