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

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

一、先看懂四个配置文件

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

文件 存什么 谁能读
/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-datamysql 账号。自己起服务时也建议建一个无登录 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 的主组是自己的同名组,同时属于 developersdocker 两个附加组。

⚠️ 常见错误

  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)才生效。

相关推荐
ai小陈1 小时前
GPU服务器租用安全配置实战:SSH密钥与端口最小化开放
服务器·人工智能·深度学习·安全·ai·gpu算力
ccino .1 小时前
Docker 容器删除卡在 Removal In Progress / Dead 解决
服务器·安全·web安全·网络安全
羑悻的小杀马特1 小时前
从写 YAML 到集群自愈:KES-Operator 把 KES 集群接进 Kubernetes 原生体系
运维·数据库·容器·kubernetes
bksczm1 小时前
MySQL基础篇之事务
linux·数据库·sql·mysql
李白客1 小时前
数据库管理工具怎么选?Navicat、DataGrip、DBeaver 六维横向对比与选型建议
运维·数据库
Ivanqhz1 小时前
BPE(Byte Pair Encoding) 算法
java·服务器·网络·深度学习·神经网络
iPad协议个微协议1 小时前
微信二次开发如何用 WechatApi 打通消息、客户和业务系统
运维·微信·自动化·微信开发·wechatapi·个人微信开发
蓝速科技1 小时前
蓝速 K10 三防平板在工业恶劣工况下的选型与应用指南
大数据·运维·数据库·人工智能·科技
bksczm1 小时前
MySQL基础篇之视图与用户管理
linux·数据库·sql·mysql