Linux用户与组管理命令大全:useradd、usermod、groupadd、passwd

Linux 用户与组管理是权限体系的地基。不管是给同事开账号、给服务建专属运行用户,还是排查"这个目录为什么没权限",绕不开的就是 useradd、usermod、groupadd、passwd 这几条命令。这一篇把它们的语法、常用参数和容易踩的坑一次讲清楚。

一、先看懂四个配置文件

所有用户和组的信息都落在四个文本文件里。改命令之前先知道它们记什么,出问题时才知道去哪查。

文件 存什么 谁能读
/etc/passwd 每个用户一行:用户名、UID、主组 GID、家目录、登录 Shell 所有用户
/etc/shadow 加密后的密码、密码过期策略 只有 root
/etc/group 每个组一行:组名、GID、组成员列表 所有用户
/etc/gshadow 组密码、组管理员(很少用) 只有 root

/etc/passwd 里每一行用冒号切成 7 段:

bash 复制代码
root:x:0:0:root:/root:/bin/bash

依次是:用户名、密码占位符(永远是 x,真密码在 shadow)、UID、主组 GID、注释信息、家目录、登录 Shell。普通用户的 UID 通常从 1000 开始(Ubuntu/Debian/Rocky 一致),1~999 是系统保留账号。

二、groupadd:创建组

语法格式

bash 复制代码
groupadd [选项] 组名

常用参数

参数 说明
-g GID 手动指定 GID,不写则自动取下一个可用值
-r 创建系统组(GID 落在系统号段内,常用于服务账号)
-f 组已存在时不报错(脚本里用)

示例与预期输出

bash 复制代码
sudo groupadd developers
sudo groupadd -g 3000 devops

确认是否建成功:

bash 复制代码
getent group developers devops

预期输出:

复制代码
developers:x:1001:
devops:x:3000:

用 getent group 而不是 cat /etc/group,是因为它在 NIS/LDAP 环境下也能查到组,写脚本更通用。

三、useradd:创建用户

语法格式

bash 复制代码
useradd [选项] 用户名

常用参数

参数 说明
-m 自动创建家目录(Ubuntu 默认行为,CentOS 上常需要显式加)
-d 路径 指定家目录位置,默认 /home/用户名
-s Shell 指定登录 Shell,如 /bin/bash、/sbin/nologin
-g 主组 指定主组(组名或 GID),不写则默认建一个同名私有组
-G 组1,组2 加入附加组(注意会覆盖,不是追加)
-c 注释 写真实姓名或用途,如 -c "Zhang San"
-u UID 手动指定 UID
-e YYYY-MM-DD 账号过期日期
-p 加密串 直接给密码(要传加密后的串,不要传明文,交互用 passwd)

示例与预期输出

示例 1:建一个能登录的普通用户

bash 复制代码
sudo useradd -m -s /bin/bash -c "Zhang San" zhangsan
sudo passwd zhangsan

第二条会提示输入两次密码。建完看一下:

bash 复制代码
getent passwd zhangsan

预期输出:

复制代码
zhangsan:x:1001:1001:Zhang San:/home/zhangsan:/bin/bash

示例 2:建一个不能登录、专给服务用的用户

跑 Nginx、MySQL 这类服务时,官方包通常自带 www-data、mysql 账号。自己起服务时也建议建一个无登录 Shell 的运行账号:

bash 复制代码
sudo useradd -r -m -s /usr/sbin/nologin apprunner

-r 建系统账号,/usr/sbin/nologin 让它不能交互式登录,但服务进程仍能以它的身份跑。

示例 3:把用户加进附加组

bash 复制代码
sudo useradd -m -G developers,docker lisi

lisi 的主组是自己的同名组,同时属于 developers 和 docker 两个附加组。

⚠️ 常见错误

  1. CentOS/Rocky 上漏 -m :很多最小化安装的系统默认不建家目录,用户登录后直接掉进 /。养成 useradd -m 的习惯。
  2. -G 当成追加用 :usermod -G 是覆盖式赋值。想"追加"必须用 usermod -aG,少写那个 a 会把用户已有的其他附加组全部清掉。
  3. -p 传明文 :useradd -p 123456 会把 123456 当成加密后的密码串写进 shadow,结果永远登不上。设密码用 passwd。

四、usermod:修改已有用户

语法格式

bash 复制代码
usermod [选项] 用户名

常用参数

参数 说明
-l 新名 修改登录名(家目录和文件不会自动改名)
-g 主组 修改主组
-aG 组 追加 附加组(-a 必须和 -G 一起用)
-d 新路径 -m 新家目录并把旧家目录内容迁过去
-L 锁定账号(在密码前加 !,禁止登录)
-U 解锁账号
-s Shell 修改登录 Shell
-c 注释 修改 GECOS 注释

示例与预期输出

改 Shell 并迁移家目录:

bash 复制代码
sudo usermod -s /bin/zsh -m -d /home/zhangsan_v2 zhangsan

这条命令同时干了三件事:换 Shell、搬家目录、把旧目录里的文件一起搬过去。

追加一个附加组而不覆盖:

bash 复制代码
sudo usermod -aG sudo zhangsan     # Ubuntu/Debian,加入 sudo 组获得提权
sudo usermod -aG wheel zhangsan    # CentOS/Rocky,对应 wheel 组

注意:用户重新登录后组权限才生效,已经开着的 SSH 会话不会自动刷新,用 groups zhangsan 确认。

临时锁掉一个账号:

bash 复制代码
sudo usermod -L zhangsan
sudo passwd -S zhangsan

预期输出(第二列 L 表示已锁定):

复制代码
zhangsan L 09/16/2026 0 99999 7 -1

五、passwd:设置和管理密码

语法格式

bash 复制代码
passwd [选项] [用户名]

普通用户不带用户名改自己的密码;root 可以改任何人的。

常用参数

参数 说明
-S 用户名 查看密码状态(是否锁定、最后修改时间)
-l 用户名 锁定(root 专用,等价 usermod -L)
-u 用户名 解锁
-d 用户名 删掉密码,变成空密码(生产环境慎用)
-e 用户名 强制下次登录改密码

示例与预期输出

让新用户第一次登录就改密码:

bash 复制代码
sudo passwd --expire zhangsan

下次 zhangsan 登录时会被强制跳到改密码流程。批量给同事开账号时常用这招。

查密码状态:

bash 复制代码
sudo passwd -S zhangsan

输出里第二个字段:P 表示有可用密码,L 锁定,NP 无密码。

⚠️ 注意事项

  • 密码复杂度由 PAM 模块(pam_pwquality)控制,不是 passwd 本身。设太短太简单会被拒绝,报错信息在 /var/log/auth.log(Debian/Ubuntu)或 /var/log/secure(RHEL 系)。
  • 不要把密码写进命令行历史。passwd 是交互式提示输入,比 echo 密码 | passwd --stdin 安全------后者会把密码留在 shell history 里。

六、配套命令:userdel、groupdel、su

  • userdel 用户名:删用户;加 -r 连家目录和邮件队列一起删。先确认没有进程还在用这个身份跑 ,ps -u 用户名 看一眼再删。
  • groupdel 组名:删组。如果这个组是某个用户的主组,删不掉,得先把那个用户的主组改掉或删掉。
  • su - 用户名:切到另一个用户。中间的横杠很关键,它会加载目标用户的完整登录环境;不带横杠切过去,家目录、环境变量都还是原来的。

七、知识扩展:useradd 的默认值从哪来

在 Ubuntu 上敲 sudo useradd tom,家目录、Shell、UID 是怎么定的?答案在两个文件:

  • /etc/default/useradd:控制是否建家目录、默认 Shell、过期日期等。
  • /etc/login.defs:控制 UID/GID 起止范围、密码最长有效期、UMASK 等。

用 useradd -D 可以直接看当前生效的默认值:

bash 复制代码
useradd -D

预期输出(节选):

复制代码
GROUP=100
HOME=/home
INACTIVE=-1
EXPIRE=
SHELL=/bin/bash
SKEL=/etc/skel
CREATE_MAIL_SPOOL=yes

其中 SKEL=/etc/skel 是个容易被忽略的细节:新建用户的家目录是从 /etc/skel 整个拷贝过来的。想让所有新用户默认带 .bashrc 别名、vimrc 之类的配置,把文件放进 /etc/skel 就行,不用每个用户单独配。

另一个高频困惑:为什么我明明把用户加进了 docker 组,却还是要 sudo docker?因为组权限在登录那一刻快照进会话,加完组后必须退出重新登录(或 newgrp docker)才生效。

相关推荐
Lsetea20 分钟前
curl用IP测试HTTPS报证书不匹配:--resolve与Host头别混用
linux·https·ssl证书·openssl·curl
Hao28524 分钟前
Windows11 下把 WSL2 Ubuntu 26.04 装到 D 盘完整
linux
Android系统攻城狮41 分钟前
Linux Gstreamer深度解析之gst_audio_encoder_get_frame_samples_min调用流程与实战(六十)
linux·运维·服务器·音视频·gstreamer音视频·音视频进阶·gstreamer音视频进阶
_upupup1 小时前
Linux中的自动化构建——make/Makefile
linux·运维·自动化
HEJOO92 小时前
Linux 设备驱动系列——使用全局工作队列
java·linux·算法
还卿一钵无情泪2 小时前
Docker 部署Unsloth 绕开环境配置难题
运维·人工智能·docker·ai·容器·nlp·干货
slimer3 小时前
07.进制转换上篇:位权展开与十进制互转
linux
顺风尿一寸3 小时前
手写迷你 Docker:用 Namespace + Cgroup v2 实现一个简单容器
linux
一木 之林3 小时前
DeepSeek Agent 开发(三)
java·大数据·linux
打工仔折腾 AI3 小时前
Docker镜像分层与卷挂载到底怎么工作:一次文件系统层面的实测分析
运维·人工智能·后端·python·docker·容器·性能优化