创建用户必须设置UniqueID、PrimaryGroupID、UserShell、NFSHomeDirectory、RealName这5个属性,缺一不可;否则将导致登录失败、家目录不可写或用户不可见。

创建用户必须设这5个属性,少一个就登录失败
用 dscl 创建用户不能只跑一条 sudo dscl . -create /Users/username 就完事——系统根本认不出这是个“可用账户”。macOS 依赖 Directory Service,缺任意一个关键属性都会导致无法登录、家目录不可写、甚至在“用户与群组”里都看不到。
-
UniqueID:必须唯一且 ≥ 501(500及以下为系统保留),例如sudo dscl . -create /Users/alice UniqueID 501 -
PrimaryGroupID:普通用户填20(对应staff组),管理员填80(admin组) -
UserShell:标准用户用/bin/zsh,禁用登录则设为/usr/bin/false(不是/bin/false) -
NFSHomeDirectory:路径必须和用户名一致,如/Users/alice;系统不自动创建该目录 -
RealName:虽非强制,但缺失会导致“用户与群组”面板显示为空白名,建议补上
漏掉 NFSHomeDirectory 或没手动建目录,SSH 登录会报 Could not chdir to home directory;UID 重复则命令静默失败,查 dscl . -read /Users/username UniqueID 才能发现。
加管理员权限 ≠ 改 UID,而是往 admin 组里塞名字
很多人误以为把 UniqueID 改成 80 就是管理员——完全错误。80 是 admin 组的 PrimaryGroupID,不是用户的 UID。管理员身份由是否属于 admin 组决定,跟 UID 无关。
- 加权限:
sudo dscl . -append /Groups/admin GroupMembership alice - 验证生效:
id alice应输出包含80(admin) - 降权(移出管理员):
sudo dscl . -delete /Groups/admin GroupMembership alice - 注意:
GroupMembership值是用户名字符串,不是 UID;大小写敏感,拼错不会报错但无效
执行后无需重启,新终端 session 即可识别权限。但 GUI 登录界面可能缓存旧状态,可注销重进或运行 killall SystemUIServer 刷新菜单栏。
隐藏用户和禁用登录是两回事,别混用
IsHidden 1 和 UserShell /usr/bin/false 解决的是不同问题:前者控制是否出现在登录界面和系统设置里,后者彻底切断交互式 shell 访问。两者可以共存,也可以单独使用。
- 隐藏但允许 SSH 登录:
sudo dscl . -create /Users/backup IsHidden 1 - 禁用所有登录(保留家目录):
sudo dscl . -create /Users/backup UserShell /usr/bin/false - 同时启用:
sudo dscl . -create /Users/backup IsHidden 1 && sudo dscl . -create /Users/backup UserShell /usr/bin/false - 取消隐藏:
sudo dscl . -delete /Users/backup IsHidden;恢复登录:sudo dscl . -create /Users/backup UserShell /bin/zsh
隐藏用户仍可通过 ssh backup@localhost 登录(只要 shell 没禁),但不会出现在 Spotlight 用户切换、登录窗口、访客列表中。禁用 shell 后,连 su - backup 都会失败,但 sudo -u backup ls /Users/backup 仍可读写文件。
查用户别用 cat /etc/passwd,它只是兼容层快照
/etc/passwd 在 macOS 上是 Directory Service 的只读导出视图,不实时、不完整——系统账户可能不出现,刚创建的用户也可能延迟数秒才同步进去。真正权威的数据源是 dscl 本地节点。
- 列所有真实用户(排除系统账户):
dscl . -list /Users UniqueID | awk '$2 >= 501 {print $1}' - 查某用户全部属性(含隐藏字段):
dscl . -read /Users/alice - 看 admin 组成员:
dscl . -read /Groups/admin GroupMembership - 批量检查多个用户是否存在:
for u in alice bob charlie; do echo "$u: $(dscl . -read /Users/$u 2>/dev/null | head -1)"; done
用 getent passwd 虽然能返回类似 Linux 的格式,但它底层也调用 Directory Service,结果和 dscl 一致;而 cat /etc/passwd 可能漏掉刚用 sysadminctl 创建的用户,或包含已删除但未清理的残留条目。
最常被忽略的一点:所有 dscl 写操作都必须加 sudo,但读操作(如 dscl . -read)不需要。另外,NFSHomeDirectory 对应的目录必须用 sudo mkdir -p /Users/username 创建,并立刻 sudo chown username:staff /Users/username,否则即使账户存在,第一次登录也会卡住或回退到 shell 提示符下无家目录。

















