w是最直接可靠的方式,读取/var/run/utmp仅显示真实活跃会话(ssh、tty、图形登录),不包含幽灵连接;推荐用w -h -u避免截断和权限干扰,输出更干净稳定。

w 是最直接可靠的方式,它读取 /var/run/utmp,只反映真实活跃会话(SSH、TTY、图形登录),不包含已断开但残留的“幽灵连接”。
用 w -h -u 避免截断和权限干扰
默认 w 输出容易被截断(尤其用户名或命令过长),且 JCPU/PCPU 计算可能因权限不足报错,掩盖真实用户。加 -h 去表头、-u 禁用 CPU 时间计算后,输出干净稳定:
w -h -u
- 第一列是用户名,第二列是终端(如
pts/0、tty1、:0) -
FROM列为???通常是 SSH 反向 DNS 解析失败,不影响判断是否在线 - 想按登录时间排序?
w默认按 CPU 占用排,此时应改用last | grep "still logged in"
脚本中快速提取用户名:优先用 who,别信 users
who 字段固定、无歧义,适合解析;users 虽简洁,但同一用户多终端会重复出现,且无法区分来源或终端类型:
- 提取当前所有登录用户名(含重复):
who | awk '{print $1}' - 去重统计实际登录人数:
who | awk '{print $1}' | sort -u | wc -l -
users输出是空格分隔单行,who am i只显示当前 shell 所属会话,二者都不适合审计场景
图形界面用户容易被漏掉,loginctl 得补上
GNOME/KDE 桌面通过 systemd-logind 管理会话,w 和 who 虽能显示 :0 或 tty7,但无法确认会话状态是否活跃。此时必须查 loginctl:
- 列出所有用户会话:
loginctl list-sessions - 查某用户所有会话:
loginctl list-sessions | grep username - 确认会话是否 active:
loginctl show-session <session-id> | grep Active</session-id> - 注意:
loginctl需要普通用户权限即可运行,无需 root
为什么 ps aux | grep sshd 不算数
有人用这个查“谁连着”,但结果常不准:
- SSHD 进程 UID 不一定等于登录用户 UID(ForceCommand、容器化 SSH 时常见)
- 网络中断后未清理的僵死连接仍占一个
sshd进程,但用户早已离线 - systemd 用户会话(如
loginctl管理的)根本不出现在ps的sshd列表里 - 真实案例:
ps显示 5 个sshd,w只显示 2 个活跃用户 —— 另外 3 个是无效残留
loginctl 就等于默认放弃对桌面用户的可见性。











