当你需要让Linux用户访问Docker、sudo、共享目录或其他受保护的资渏时,通常需要将该用户添加到一个组。用户组允许你一次性管理多个用户的权限,而不是为每个账户单独修改权限。

本指南介绍如何将现有用户添加到Linux用户组、将用户添加到多个组、更改用户的主组以及验证变更是否生效。

用户组分为两类型:

主组(Primary group):在创建账户时分配给用户。通常主组名称与用户名相同。当用户创建文件时,文件的组会被设置为该用户的主组。主组保存在/etc/passwd文件中。

次级(补充)组(Secondary/supplementary groups):用于授予额外的权限。例如,将用户添加到docker组允许其在不使用sudo的情况下运行Docker命令。

每个用户恰好有一个主组,可以属于零个或多个次级组。

仅根用户或具有sudo权限的用户可以修改组成员资格。

快速参考

任务                                          命令
查看用户所属组                              id username
仅列出组名称                              groups username
列出所有系统组                              getent group
列出某组的成员                            getent group groupname
检查用户是否存在                          getent passwd username
检查组是否存在                            getent group groupname
将用户添加到组                            sudo usermod -a -G groupname username
将用户添加到多个组                          sudo usermod -a -G group1,group2 username
将用户添加到组 (Debian, Ubuntu)            sudo adduser username groupname
将自己的账户添加到组                        sudo usermod -aG groupname $USER
以新组启动shell                            newgrp groupname
更改主组                                  sudo usermod -g groupname username
创建带组的用户                            sudo useradd -g primary -G sec1,sec2 username
从组中移除用户                            sudo gpasswd -d username groupname
创廻一个组                                sudo groupadd groupname
删除一个组                                sudo groupdel groupname

查看用户所属组

在修改组之前,检查用户当前的组成员资格很有用。

id命令显示用户的UID、主组和所有次级组:

id linuxize
uid=1000(linuxize) gid=1000(linuxize) groups=1000(linuxize),27(sudo),1001(developers)

groups命令仅打印组名称:

groups linuxize
linuxize : linuxize sudo developers

如果省略用户名,两个命令都会显示当前登录用户的信息。

列出系统个所有组

列出系统个所有组:

getent group

列出某个特定组的所有成员:

getent group docker
docker:x:993:deploy

将用户添加到组

在更改组成员资格之前,请确保用户和组都已经存在。usermod命令不会为你创建缺失的用户或组。

使用getent passwd检查用户:

getent passwd linuxize

使用getent group检查组:

getent group docker

如果两个命令都返回了条目,你就可以将用户添加到该组。

要将现有用户添加到次级组,使用usermod -a -G命令,后跟组名和用户名:

sudo usermod -a -G groupname username

例如,将用户linuxize添加到docker组:

sudo usermod -a -G docker linuxize

警告:添加用户到组时始终使用-a(append,追加)选项。如果省略-a,该用户将被从所有未在-G后列出的次级组中移除。

-a和-G选项通常一起写作-aG,是同一命令的简写形式。

成功时,命令不会产生任何输出。使用id验证新成员资格:

id linuxize
uid=1000(linuxize) gid=1000(linuxize) groups=1000(linuxize),27(sudo),993(docker),1001(developers)

组变更在用户注销并重新登录后生效。要在当前会话中应用变更,运行:

newgrp docker

newgrp命令以所选组作为活跃组启动一个shell。对于普通登录会话,注销并重新登录是更干净的选择。

将用户添加到多个组

要一次性将用户添加到多个次级组,请用逗号(不可有空格)分隔组名:

sudo usermod -a -G group1,group2,group3 username

例如,将linuxize添加到docker和developers组:

sudo usermod -a -G docker,developers linuxize

不要在逗号后加空格。usermod期望一个逗号分隔的列表。

在Debian和Ubuntu上使用adduser

Debian、Ubuntu及其衍生版自带adduser命令。传入一个现有用户和一个现有组,它会将该用户添加到该组:

sudo adduser username groupname

例如,将linuxize添加到docker组:

sudo adduser linuxize docker

结果与usermod -aG docker linuxize相同。没有需要记住的追加标志,因此不会意外将用户从其他组中删除。

较旧的发行版会打印简短的确认信息。Ubuntu 26.04和Debian 13自带adduser 3.138或更新版本,该版本会将这些状态行从控制台隐藏。命令仍然成功。使用id验证结果:

id linuxize

这种两参数形式属于Debian及其衍生版。在Fedora、RHEL及其衍生版上,adduser是useradd的符号链接,因此那里请使用usermod。

将用户添加到sudo或wheel组

管理访问权是更改用户组最常见的原因。组名取决于发行版。

在Debian、Ubuntu及其衍生版上,sudo组的成员可以root身份运行命令:

sudo usermod -aG sudo linuxize

在Fedora、RHEL及其衍生版上,相同的权限来自wheel组:

sudo usermod -aG wheel linuxize

两个组的权力都来自/etc/sudoers中的同一条规则。在Debian和Ubuntu上该规则为%sudo ALL=(ALL:ALL) ALL,在Fedora和RHEL上为%wheel ALL=(ALL) ALL。百分号标记这是一条组规则而非用户规则。

如果不确定系统使用哪个组,可以直接阅读该规则:

sudo grep -E '^%(sudo|wheel)' /etc/sudoers

用户必须注销并重新登录,新的权限才会生效。

更改用户的主组

要更改用户的主组,使用带小写-g选项的usermod:

sudo usermod -g groupname username

例如,将用户linuxize的主组更改为developers:

sudo usermod -g developers linuxize

注意区别:-G(大写)设置次级组,-g(小写)设置主组。

创建带组的用户

useradd命令可以在创建新用户时同时分配主组和次级组:

sudo useradd -g users -G wheel,developers nathan

这会创建一个用户nathan,主组为users,次级组为wheel和developers。

从组中移除用户

要从组中移除用户,使用带-d选项的gpasswd命令:

sudo gpasswd -d username groupname

例如,将linuxize从docker组中移除:

sudo gpasswd -d linuxize docker

创建和删除组

创建新组:

sudo groupadd groupname

删除组:

sudo groupdel groupname

你无法删除作为某用户主组的组。请先更改该用户的主组。

故障排除

组变更在当前shell中未生效

Linux在会话开始时读取用户的组。如果id username显示了新组,但用户仍无法访问资源,请注销并重新登录。要获得一个带新组的临时shell,运行newgrp groupname。

usermod: user 'username' does not exist

用户名缺失或拼写错误。使用getent passwd username检查账户。如果需要先创建用户,请使用useradd或发行版的用户管理工具。

usermod: group 'groupname' does not exist

组必须在添加用户之前存在。使用getent group groupname检查。如果缺失,请用sudo groupadd groupname创建,然后再次运行usermod -a -G groupname username。

运行usermod -G后用户丢失了其他组的访问权

这是在使用-G时未使用-a时发生的。该命令会将用户的次级组替换为-G后列出的组。使用sudo usermod -a -G group1,group2 username重新添加缺失的组,然后用id username验证。

adduser username groupname在Fedora或RHEL上失败

在Fedora、RHEL及其衍生版上,/usr/sbin/adduser是useradd的符号链接。该命令仅接受一个账户名,因此会打印用法错误并不会将用户添加到组。在这些系统上使用sudo usermod -aG groupname username。

常见问题

如果我忘记了usermod -G的-a标志会怎样?

该用户将从除命令中列出的组之外的所有次级组中移除。这是管理组时最常见的错误。始终一起使用-a -G。

组变更会立即生效吗?

不会。用户必须注销并重新登录,新的组成员资格才会生效。你可以通过运行id username验证;变更会立即显示在那里,但用户的活跃会话仍然使用旧的组。

usermod中-g和-G的区别是什么?

小写-g设置用户的主组。大写-G设置次级(补充)组。与-a一起使用时,-G会追加到现有列表而非替换它。

adduser和usermod在组变更上有什么区别?

在Debian和Ubuntu上,sudo adduser username groupname一步将现有用户添加到现有组。usermod -aG groupname username做同样的事,并且在每个发行版都适用。在基于Debian的系统上将adduser用于交互式工作,在脚本或Fedora/RHEL上使用usermod。

如何将我自己的账户添加到组?

使用$USER变量,这样就不需要键入用户名:sudo usermod -aG docker $USER。变更不会到达你所在的shell。请注销并重新登录,或使用newgrp docker启动新会话。

如何查找系统上存在哪些组?

运行getent group列出所有组,或运行getent group groupname检查特定组是否存在及查看其成员。

一个用户可以属于多个主组吗?

不可以。每个用户恰好有一个主组。要授予对多个资源的访问权,请使用次级组。

总结

usermod -a -G命令将现有用户添加到Linux中的次级组。使用id、groups和getent验证变更,并且在使用-G时始终包含-a,以保持现有的组成员资格完整。