linux中无统一“所有用户”视图;/etc/passwd仅含本地账户(含服务账户),需按uid≥1000、有效shell等条件筛选真实人类用户,并结合home目录、密码状态及权限谨慎识别。

Linux 中没有“所有用户”的统一视图,/etc/passwd 里列出的是本地系统账户(含服务账户),不是你想象中的“登录过的人”或“活跃用户”。直接 cat 它就能看到基础列表,但得会筛、会判、会防误读。
看本地用户:从 /etc/passwd 提取有效登录账户
系统用户和普通用户都存在 /etc/passwd,但很多是服务账户(如 daemon、syslog),UID 小于 1000(Ubuntu/Debian)或 500(RHEL/CentOS)的通常不用于交互登录。
- 只显示 UID ≥ 1000 的用户(主流桌面发行版):
awk -F: '$3 >= 1000 && $3
- 排除
/sbin/nologin和/bin/false这类禁止登录的 shell:awk -F: '$3 >= 1000 && $7 !~ /(nologin|false)$/{print $1}' /etc/passwd -
$7是 shell 字段,$3是 UID;65534是 nfsnobody 类账户上限,避免误吞
查当前登录用户:别把 who 和 users 当成用户列表
who、w、users 只反映此刻谁在终端或 SSH 上“挂着”,不是系统账户清单。它们不显示未登录用户,也不显示被禁用但存在的账户(比如刚创建还没登录过的用户)。
-
who显示登录终端、时间、来源 IP(SSH 场景有用) -
w多带一列正在运行的命令,适合排查占用 - 这些命令对容器环境、systemd --user 会话、X11 本地登录支持有限,别指望全覆盖
识别真实人类用户:结合 home 目录和密码状态
仅靠 UID 和 shell 不够保险——有人可能改了 shell 或手动建了低 UID 账户。更稳的方式是检查是否具备“可登录人类用户”的典型特征:
- home 目录存在且非空:
ls -ld /home/* 2>/dev/null | awk '{print $3}' | sort -u(列出实际有 home 的用户名) - 密码是否已设置(非锁定):
sudo getent shadow | awk -F: '$2 != "*" && $2 != "!" {print $1}'(*和!表示无密码或被锁) - 注意:
getent shadow需要 root 权限,且某些系统(如启用了 sssd 或 LDAP)会返回域用户,此时结果超出本地范围
别漏掉系统级特殊账户和权限陷阱
有些账户虽然 UID 低、没 home、shell 是 /bin/false,但承担关键功能(如 www-data、mysql)。删它们或改权限可能直接让服务崩掉。
- 用
getent passwd替代直接读/etc/passwd,它能合并 LDAP/NIS 等后端数据(如果配置了) -
compgen -u只输出当前 shell 环境能补全的用户名(基于 cache,不一定实时,慎用于审计) - 脚本中解析
/etc/passwd时,务必用awk -F:而不是cut -d:,因为注释字段(GECOS)里可能含冒号
真正难的不是“怎么列出来”,而是判断“这个用户该不该出现在你的管理视野里”——是服务账户、遗留测试账户、还是被遗忘的提权入口。每次看用户列表,最好顺手 sudo ls -l /home 和 sudo passwd -S <username></username> 交叉验证一下。











