首页  /  Linux  /  正文

改了用户组,为什么权限还是不生效?

Linux 2026-09-14📖 6 分钟👁 —

这是我踩过最"玄学"的坑之一:明明把用户加进 sudo 组了,sudo 还是报 user is not in the sudoers file。

现象

$ sudo apt update
dsh is not in the sudoers file.  This incident will be reported.

但查一下,用户明明已经在组里了:

$ id dsh
uid=1000(dsh) gid=1000(dsh) groups=1000(dsh),27(sudo)   # ← 有 sudo 组!

$ getent group sudo
sudo:x:27:dsh                                            # ← 也确实在

系统记录里在,实际却不生效——这就是它"玄学"的地方。

真正的原因

关键在于:查看权限时,要分"系统记录的"和"当前会话持有的"。

$ id dsh          # 查"系统记录"(读配置文件)→ 有 sudo
$ id              # 查"当前会话"(读进程凭证)→ 没有 sudo

因为 Linux 进程在创建那一刻就把用户组快照写进了凭证里(struct cred)。之后你改 /etc/group,已经存在的会话完全不知道。

用户组变更,只对"新登录的会话"生效。

怎么解

方法 1:重新登录(最常用)

exit        # 退出
ssh user@服务器   # 重新登录 —— 新会话就带上新组了

方法 2:用 newgrp 切换(不退出)

newgrp sudo        # 启动一个带 sudo 组的新 shell

方法 3:su - 重新加载

su - $USER

更隐蔽的情况:长连接池

我遇到的真实场景更绕:SSH 客户端有连接池,一直复用同一条老连接。你"重新连接"看起来是新会话,其实池子里还是那个老会话——怎么试都不生效。

# 排查思路:换一条全新的连接试试
ssh -o ControlMaster=no -o ControlPath=none user@服务器 id
教训:长连接虽然快,但会掩盖环境变更。
排查诡异问题时,第一步永远是——换个干净会话再试。

一张排查清单

检查项命令看什么
系统记录id 用户名组里有没有
当前会话id实际拿到的组
组配置getent group sudo成员列表
sudo 规则sudo -l你能执行什么

总结

  1. id 和 id 用户名 看的不是一回事
  2. 组变更需要新会话才生效
  3. 长连接池会让"重新登录"变成假动作
  4. 排查时先排除环境问题,再怀疑配置