w -h -u 是查看当前在线用户及活动状态的首选命令,它读取 /var/run/utmp,显示全部真实会话(含图形、SSH、TTY),避免截断与权限干扰,且不误判僵死连接。

直接用 w -h -u 就能看到当前所有在线用户及其活动状态,这是最准、最实用的命令。其他命令要么信息残缺,要么容易误判。
为什么 w -h -u 是首选
它读取的是 /var/run/utmp,和 who、users 同源,但额外带进程上下文;加 -h 去掉表头避免截断,加 -u 避免因权限问题导致 CPU 时间字段显示异常或报错。
-
w默认按 CPU 占用排序,高负载时活跃度低的用户可能被挤出屏幕 ——-h -u能稳定输出全部会话 - 图形界面用户(如 GNOME)在
:0或tty7登录,w会正常显示,而ps aux | grep sshd完全漏掉这类会话 - 同一用户开多个终端(比如
root同时在pts/0和pts/1),w每行一条,不合并也不去重,符合真实登录态
who 和 users 的适用边界
who 输出字段固定,适合脚本解析;users 只输出空格分隔的用户名,连终端都不带 —— 它们不是“不准”,而是“信息太少”。
- 要提取纯用户名列表供后续处理:
who | awk '{print $1}' | sort -u(注意:这不是统计“人数”,只是去重后的用户名集合) -
users里重复出现的用户名表示多会话,不能直接wc -w当作“登录人数”——比如alice alice bob是 2 个用户、3 个会话 -
who am i只返回当前 shell 所属会话,别拿它当全局判断
别信 ps aux | grep sshd
这个写法在运维笔记里很常见,但实际场景中极易出错:sshd 子进程 UID 不一定等于登录用户 UID(尤其用了 ForceCommand 或容器化 SSH),且无法区分已断连但未超时清理的僵死连接。
- 真实现象:
ps显示 5 个sshd:进程,w只显示 2 个用户 —— 另外 3 个是网络中断后残留的僵尸连接 - systemd 用户会话(
loginctl list-sessions)完全不出现在ps的sshd列表里 - 如果真要查 SSH 连接数,应该看
ss -tnp | grep :22,但这也只反映 TCP 连接,不等于有效登录会话
last | grep "still logged in" 的陷阱
它从 /var/log/wtmp 读历史记录,理论上能补全 utmp 的盲区,但实际依赖日志轮转策略和系统重启频率。
- 服务器刚重启过,
wtmp里可能只有重启后的记录,漏掉上次运行期间的长期登录用户 -
last输出的still logged in条目,和w的实时结果不一致时,优先信w—— 因为utmp是内核维护的实时会话快照 - 普通用户默认无权读
wtmp,last常需sudo,而w和who普通用户就能跑
真正要确认“此刻谁在系统里”,就盯住 w -h -u 的输出;需要进一步排查某个用户干了什么,再结合它的 WHAT 列看命令,别绕远路猜。图形会话、SSH、本地 TTY 全覆盖,且不依赖外部服务或日志完整性。


















