Linux用户管理实战:从用户创建到删除的底层逻辑与权限配置 2. 用户管理到底在管什么说实话很多人学Linux用户管理一开始就被useradd、usermod、groupadd这一堆命令劝退了。命令本身不难难的是理解“为什么要这么设计”。在Linux的世界里用户和组不是单纯的“账号”和“群聊”它们本质上是一套权限分配系统。你可以把Linux比作一栋大楼用户是住客组是楼层或房间的钥匙分组权限是每个房间的门禁规则。你作为系统管理员root就是这栋大楼的物业——所有房间你都能打开但你不能天天替每个住客开门所以你要做的是“分钥匙、设门禁、登记入住记录”。这套系统解决了三个核心问题隔离A用户不能乱删B用户的文件就像住客不能随便进别人房间。协作一个项目组共用某些文件组权限让“同一把钥匙开同一扇门”成为可能。审计每个文件都有归属标记出了事能查“是谁的锅”。这篇文章聚焦“第3关——用户/用户组编辑”我会把用户创建、修改、删除以及用户组的联动操作按照一个完整项目流程拆开讲。适合刚入门Linux的读者也适合已经会用一点命令但没系统梳理过的人查漏补缺。做人要实诚一点讲明白账号管理的底层逻辑不装深沉也不说废话。2. 用户和组的底层关系4个文件搞清楚一切2.1 用户信息在哪儿/etc/passwd 和 /etc/shadow很多教材让你死记useradd -m -u -g -s这些参数但如果你不知道参数到底改的是哪个文件记了也是白记。Linux把用户信息存在两个核心文件里/etc/passwd和/etc/shadow。/etc/passwd每一行代表一个用户用冒号分成7段长这样devops:x:1001:1001::/home/devops:/bin/bash这7段分别是用户名、密码占位符x表示真正的密码在shadow里、UID、GID、注释信息、家目录、登录Shell。这里要特别说一句现代Linux里/etc/passwd里那个x只是占位符真正的密码哈希在/etc/shadow里而且shadow文件只有root能读普通用户连看都看不了。这是最基本的安全设计。/etc/shadow长这样devops:$6$salt$verylonghash...:18800:0:99999:7:::字段分别是用户名、加密后的密码、最后一次改密时间从1970年1月1日算起的天数、密码最小使用天数、最大使用天数、警告天数、宽限天数、账户过期时间、保留字段。提示刚开始学的时候别一上来就去改这两个文件但强烈建议你cat /etc/passwd多看几遍把字段含义和后面的命令对应起来。你如果理解了文件结构useradd的所有参数就像是往文件里填字段心里就有底了。2.2 组信息在哪儿/etc/group 和 /etc/gshadow组的信息也存在两个文件/etc/group存组名、GID、组成员/etc/gshadow存组密码一般不用。/etc/group每行也是冒号分隔4段devops:x:1001:zhangsan,lisi分别是组名、组密码占位符、GID、组成员列表。注意组的成员列表不是全部成员而是“次要成员”。每个用户在passwd里还有一个“主要组”的GID它在group文件里不显示在成员列表中。这个主组和次组的区别后面实操里会遇到很多坑。这里有个生活化的解释主组就像你的“默认工位所在部门”你入职时就被划到某个部门下次组则像是“你可以参与的项目组”可以同时挂好几个。文件默认归属是看你“主要组”而能不能读写某个协作目录取决于你“所有组里有没有对应的权限”。2.3 文件权限和用户组怎么联动第3关如果只讲命令不讲权限联动那学了也白搭。ls -l输出里第一列第三个字符位置就是“其他用户”的权限第二个字符位置是“所属组”的权限比如drwxr-xr-- 2 devops devops 4096 Jan 10 10:00 shared这一段的意思devops用户对shared目录有rwxdevops组里的成员有rx可进入、可列出但不能写其他用户只有r能看名字进不去。如果你想建一个“部门共享目录”正确姿势就是把目录所属组改成相关组然后设好组权限而不是给“其他用户”开权限。这一套逻辑掌握之后很多不小心把home目录权限搞得乱七八糟的问题就能绕开。3. 实操准备与命令速览动手前先搭环境3.1 环境要求与提前准备实操环境不挑普通的虚拟机或者云服务器都行。我用的是某虚拟机上装的一个纯命令行Linux发行版没有图形界面操作起来更接近生产环境。正式开始前先确认几件事你当前是root或者有sudo权限。用户管理几乎所有命令都要root权限。确认系统时间是对的。后面shadow文件里那个“最后一次改密时间”是按天数算的时间不对会引发诡异的密码策略问题。准备好一个干净的测试环境别在生产服务器上瞎练。用户管理命令执行之后影响面很大新手阶段拿物理机练容易出事。验证身份的姿势很简单whoami id输出如果是root或者uid0(root)就可以往下走了。3.2 核心命令速查表先记住这些再动手我把这一关最常用的命令整理成一张速查表命令不复杂难的是组合使用时的逻辑。命令作用常见参数useradd创建用户-m 建家目录-s 指定shell-G 附加组passwd设置或修改密码--stdin 从标准输入读密码脚本用usermod修改用户属性-l 改用户名-aG 追加组-s 改shelluserdel删除用户-r 连同家目录和邮件目录一起删groupadd创建用户组-g 指定GIDgroupmod修改用户组-n 改组名groupdel删除用户组无特殊参数gpasswd管理组成员-a 添加成员-d 删除成员id查看用户/组信息直接跟用户名注意很多教程会建议你用adduser在某个发行版系列下它是个交互式前端本质上调用的还是useradd。我建议你从useradd开始学因为它参数齐全、行为可控适合脚本化操作也更容易理解底层逻辑。交互式工具适合新手体验但不适合系统化学习。3.3 命令帮助工具的使用技巧Linux的好处是命令都有帮助文档但很多新手被man文档吓退。实用一点的做法是man useradd如果英文文档看着吃力先重点看SYNOPSIS语法概要和OPTIONS部分的参数说明。每个参数都有示例比自己瞎猜强。我自己的习惯是动手新命令之前先看一遍man里的“描述”和“选项”然后打开一个空目录做实验确认行为符合预期再上真实环境。这个习惯能省下很多“改错文件、误删数据”的麻烦。4. 用户创建全流程从命令到文件变化的完整拆解4.1 最基础的用户创建useradd的最小命令先演示一个最简单的场景创建用户codeuser。useradd codeuser很多新手执行完发现一会儿能用一会儿不能用然后慌慌张张来问“为什么没有家目录”“为什么不能登录”。原因很简单这个命令只是“创建了一个账号记录”创不创建家目录、能不能登录取决于发行版的默认配置以及你的参数选择。我建议新手从完整命令开始useradd -m -s /bin/bash -d /home/codeuser -c Code Project User codeuser passwd codeuser这里每个参数都是有用的-m立即创建家目录/home/codeuser。不加这个参数在某些系统上就没有家目录登录后落在根目录。-s /bin/bash指定登录Shell为bash不指定的话可能被设为默认的sh或者其他shell交互体验和脚本语法都会受影响。-d /home/codeuser显式指定家目录路径。不加的话默认是/home/用户名但显式写出来更清晰尤其适合以后要自定义路径的人。-c Code Project User添加一段用户注释信息相当于“备注”。这个字段在/etc/passwd第5段方便知道这个账号是干嘛的。passwd codeuser是给账号设置密码。这一步必不可少不然账号虽然有记录但没有密码无法正常登录SSH密钥登录的场景另说。创建完成之后立刻验证id codeuser ls -ld /home/codeuser你会看到类似这样的结果uid1001(codeuser) gid1001(codeuser) groups1001(codeuser) drwxr-x--- 2 codeuser codeuser 4096 Jan 12 10:20 /home/codeuser到这一步你才算真正创建了一个“完整可用”的用户。4.2 用户创建背后的默认逻辑不同发行版的坑这里有一个非常重要的知识点不同Linux发行版对useradd的默认行为不同。比如“某个系”的发行版useradd默认会自动创建家目录还会从/etc/skel复制一份隐藏配置文件到新家目录而“另一个系”的发行版默认行为则是不建家目录、不设密码。很多踩坑事故就源于网上教程抄来抄去没注意自己系统的默认行为。所以每次新建用户前先用下面命令看当前发行版的默认配置grep -E ^HOME|^SHELL|^CREATE_MAIL_SPOOL|^USERGROUPS_ENAB /etc/default/useradd我当初在“某系统”上入职时接手的一台服务器就是管理员每次useradd不带-m创建了一批用户结果所有用户登录后都落在/根目录下能用但极其别扭还出现过家目录文件误放在根目录的情况。排查到最后才发现就是个参数习惯问题。实操心得如果你完全没有偏好最稳妥的组合是useradd -m -s /bin/bash 用户名然后passwd 用户名设置密码。这套组合在任何主流发行版上都不会出大错。等你熟练了再按需加-u指定UID、-G指定附加组。4.3 设置密码的讲究passwd的交互与非交互用法给用户设密码有几种方式新手最容易踩坑的是“写脚本时不知道如何自动设置密码”。手动场景下直接执行passwd codeuser按提示输两遍密码即可。但脚本里不能手动输这时候要用--stdin选项从标准输入读取密码echo MyPassword123 | passwd --stdin codeuser这个方法在脚本里很常见。但安全性注意密码会出现在shell历史里。生产环境建议用chpasswd命令echo codeuser:MyPassword123 | chpasswd两种方式效果一样chpasswd更通用推荐在脚本里使用。设置完密码后再强调一次密码本身要复杂别用123456这种一台上了公网的机器被扫到弱密码账号是迟早的事。4.4 批量创建用户的思路有时候要一次性创建多个用户比如给一批新同事开账号。手动一条条敲useradd虽然能完成任务但效率太低。可以一行循环搞定for u in alice bob carol; do useradd -m -s /bin/bash $u; echo $u:InitialPass123 | chpasswd; done脚本里做的三件事创建用户、自动建家目录、设置初始密码。测试时用一个文本文件读入用户名列表会更实用但这里先提个思路别一上来就追求完美脚本。注意批量建用户虽然爽但后患也多。比如家目录权限、用户Shell、初始密码是否需要首次登录强制修改等问题建议在批量脚本里提前规划好否则建完50个账号再一个个改你会怀疑人生。5. 用户修改与组管理真正的日常操作5.1 usermod改用户属性的三个常用场景某个用户过一段时间可能会改岗位、换部门、换登录Shell这些都是usermod的活儿。我只挑三个最常用的场景展开。场景一把用户加到附加组里。这是协作场景最常用的操作。例如codeuser需要加入devops组才能访问共享目录usermod -aG devops codeuser-a是append的意思跟-G搭配使用“追加”到附加组列表而不是覆盖。很多人不改现有组直接-G结果把用户原有的附加组全冲掉了。这个坑我踩过有一次我想把某同事加到项目组直接usermod -G project codeuser把人家的多个组权限全干掉了差点出事。后来养成习惯-G必须配-a一起用除非你确实想覆盖。场景二修改用户的主组。假设codeuser原来主组是codeuser现在要归到devops组usermod -g devops codeuser改完看id codeusergid那一项变了。要理解的是主组决定新建文件时的默认归属组所以这个修改影响的是“以后这个用户新建文件属于哪个组”而不是立刻改变已有文件的归属。场景三修改用户登录Shell。比如原来用bash现在想换zsh需要先安装zshusermod -s /usr/bin/zsh codeuser改完了立刻验证grep codeuser /etc/passwd最后一段变成/usr/bin/zsh。如果用户当前在线这个改动要下一次登录才生效。5.2 组管理的完整操作groupadd、groupmod、groupdel组管理比用户管理简单一些但也有很多细节值得记录。创建组groupadd devops如果希望指定GID加-g参数比如groupadd -g 2001 devops。手动指定GID的场景一般是“和某台服务器保持一致方便迁移”否则交给系统自动分配就行自动分配一般从1000之后递增这里说的GID范围根据发行版不同有差异建议自己用/etc/login.defs确认。修改组名groupmod -n newname devops这句把组devops改名为newname然后需要同步更新相关文件里引用的组名。其实系统会自动改掉/etc/group里的组名但已经被分配到该组的用户所属组也会变成新名称。这里有一个坑如果一个目录此前所有者为devops组改完组名后目录显示的所属组会变为newname——这是因为系统记录的是GID而非字符串显示时按新名字展示。除非你手动重新chgrp否则旧名字不会出现在任何地方。删除组groupdel devops删除组有个限制条件如果某个用户的主组就是这个组组删不掉。系统会报错提示“cannot remove the primary group of user”。这时要么先把用户主组改成别的组要么先删除用户再删组。附加组成员则不受影响因为附加组只是“用户列表里的一个关联项”。5.3 gpasswd不常用但很好用的组成员管理命令usermod -aG适合管理员操作但偶尔也会遇到“只管理某一个组”的场景。gpasswd命令可以做组级管理gpasswd -a codeuser devops # 把codeuser加入devops组 gpasswd -d codeuser devops # 把codeuser从devops组移除它还能设置组管理员让指定用户有权管理这个组的成员。如果只想给某个非root用户分配“管理这一组成员”的权限可以用gpasswd -A codeuser devops组管理员可以把自己或别人加入/移出该组。这个场景在“部门负责人自己管理组内成员”时很实用不用每次都找root操作。5.4 主组和附加组的区别面试常考实操更要懂主组和附加组的概念说起来简单但实际上手管理时经常绕晕。用一个具体场景解释假设codeuser的主组是devops附加组是docker和www-data。他在/home/codeuser目录下新建一个文件cd /home/codeuser touch test.txt ls -l test.txt输出里文件所属组显示为devops——因为新建文件的默认组是主组不是附加组。如果想让新建文件自动归属某个协作组要改目录的setgid位文件权限后面那个s让目录下新建文件自动继承目录的组。这是高级玩法先记住结论主组决定新建文件的默认归属组附加组决定你能访问哪些共享资源的权限。6. 用户删除与清理善后工作直接决定稳定性6.1 userdel的安全删法删除用户是管理员日常操作里风险最高的之一。如果只是简单敲一个userdel codeuser系统只删掉/etc/passwd和/etc/shadow里的账号记录但/home/codeuser家目录、/var/spool/mail/codeuser邮件目录以及这个用户拥有的其他文件全都留在原地。文件还在但归属的UID那一串数字看起来就很乱时间久了会积累一堆“无主文件”。正确做法是连同家目录一起删除userdel -r codeuser-r参数会把家目录和邮件目录一起删掉。但是注意这只是把常规文件删了如果该用户在其他目录下还有文件-r并不会帮你清理。这些遗留文件会变成“UID 未知”的孤儿文件清理起来很麻烦。要找出某用户拥有的所有文件可以用find命令find / -user codeuser -ls 2/dev/null提示执行这条命令前先想清楚全盘扫描会有点慢在数据量大的服务器上还可能产生IO压力。先确认清楚再动手不要一上来就在生产环境全盘扫描。6.2 删除用户前的检查清单删用户前建议按下面顺序过一遍确认这个用户确实是“废弃账号”和同事、和需求方确认别删错人。确认没有进程正在以这个用户身份运行ps -u codeuser能看到输出就说明有进程在用强行删除会导致进程异常。确认用户的cron任务crontab -u codeuser -l看看有没有计划任务很多运维事故都来自“删了用户忘了删cron定时任务还在偷偷跑”。确认文件归属上面说的find -user扫一遍把重要文件提前备份或转移。最后才是userdel -r。我见过最严重的用户删除事故之一某公司清理离职员工账号时删完用户后发现那个用户之前创建的一堆数据库备份文件堵在临时目录里因为没了属主新管理员不敢动也不敢删最后只能root手动改属主再慢慢归档。所以善后永远比删除本身重要。6.3 把用户“禁用”而不删除冻结账号的正确姿势有些场景不想删账号但想让用户无法登录。比如员工休假、账号疑似被盗。可以给密码加上“锁定”标记也可以直接“过期”。锁定密码用passwd或usermod都能实现usermod -L codeuser # 锁定密码 usermod -U codeuser # 解锁密码密码锁定后最直观的表现是/etc/shadow里密码字段前面会多一个感叹号!。这种方式相当于把钥匙撕了账号还在但用密码上不了锁。禁用账号更彻底的方式是指定一个不可登录的Shellusermod -s /usr/sbin/nologin codeuser这样即使密码正确也无法登录交互式Shell。这种方式常用于“服务账号”——比如nginx运行账号本来就不需要登录。把服务账号的Shell设为nologin是安全基线里的常见要求。如果想让账号在指定时间后自动过期用chage命令chage -E 2025-12-31 codeuser这个命令把账户过期时间设到2025年底。到期后这个用户即使密码正确也无法登录。适合“临时账号”或者“外包人员到期的账号”。6.4 删除组时遇到的坑删除组同样有讲究。假设devops组已经被删了但很多用户的主组还是它这些用户的GID会变成“悬空”状态——id命令查不到组名只显示数字。这种状态不影响登录但会影响文件显示、权限检查也会给排查带来很多麻烦。我在实操中遇到过一个情况某系统管理员为了清理解散的项目组一天之内连续删了十几个组结果第二天一堆用户登录后groups输出全是纯数字文件所属组显示也是纯数字。排查了很久才发现是删组时没检查“是否还有其他用户主组指向它”。所以删除组之前先查getent passwd | awk -F: $4 组GID {print $1}看哪些用户的主组是这个组有就先改掉再删。7. 常见问题排查与避坑路书7.1 我建了用户为什么登录不了这是被问得最多的一个问题原因一般有四种密码没设置useradd创建后没有执行passwd账号有记录但没钥匙。Shell设置不对/bin/false或/usr/sbin/nologin被用作Shell了。这类Shell专门用于禁止登录比如服务账号。普通用户如果被设成这样就登录不了。账号被锁定shadow里密码字段开头有!代表锁定状态需要usermod -U解锁。家目录不存在或权限不对用户登录时如果家目录不可访问有的系统会拒绝登录有的会落到/。排查三步走grep 用户名 /etc/passwd grep 用户名 /etc/shadow ls -ld /home/用户名第一眼看Shell是不是/bin/bash第二眼看密码字段有没有!第三眼看家目录是否存在且属主是否正确。三次检查做下来90%的问题都能定位。7.2 为什么明明把用户加进组了还是不能访问目录这个坑非常常见原因往往不是组没加成而是当前登录会话没有刷新组信息。用户已经在系统里登录了这个时候你用usermod -aG devops codeuser把用户加进了组用户在当前会话里依然无法访问新组的文件因为组信息是在登录时就缓存在进程里的不会自动更新。解决办法有几种让用户退出重新登录。对当前正在运行的其他进程用newgrp devops临时切换组。如果是测试环境可以exec su - 用户名重新加载一次登录Shell。另外还有一种可能目录本身对组没有分配权限。比如你加了组但目录的权限是drwxr-x---组没有写权限那你加进去也只能看不能改这不算bug是正常的权限设计。看清目录权限再排查别总以为是组没加成。7.3 为什么我看不到/不能读/etc/shadow/etc/shadow权限是000或640普通用户看不到内容连cat都被拒绝。这是安全设计不是bug。如果你用普通用户身份执行sudo cat /etc/shadow还提示权限不够多数是sudo配置里没给这个用户授权。可以用root身份或者有sudo权限的管理员身份查看。再看/etc/passwd这个文件权限通常是644所有用户可读。所以“看用户列表”是可以的但千万别把passwd里的内容当作完整密码信息——它里面只有占位符。7.4 批量操作时怎么避免“误伤”其他用户批量场景最常见的问题是本来只想处理一批用户结果循环语句或参数把别的用户也改了。比如我之前说过usermod -G不带-a会覆盖附加组这在循环里尤其危险——如果一个用户原本有很多组循环里只写了一个组名执行完之后他原来的所有附加组就都没了这种“静默事故”很难察觉但损失很大。批量操作建议遵循三个原则每次操作前先打印将要执行的命令人工确认一遍echo输出别直接执行。批量操作前先把目标用户列表备份getent passwd /tmp/users_backup_$(date %F).txt。操作后再批量验证比如id 用户1 用户2 用户3 ...看输出是否符合预期。7.5 常见问题速查表现象常见原因解决方式useradd后无法登录没设密码或Shell不可登录passwd设密码usermod -s指定bash用户被加进组但访问不了共享目录当前会话没刷新 / 目录组权限不足重新登录或newgrp检查目录权限删组报错提示“primary group”还有用户的主组是该组先改用户主组再删组用户家目录不见了创建时没加-m手动mkdir并cp /etc/skel内容chown修复文件和目录显示为数字属主用户或组已被删除find查归属chown给现有用户或合并无法修改用户密码当前用户不是root或者sudo权限不足切换到root或配置sudoer规则修改用户名后文件属主没变usermod -l只改名字不改UID需要chown -R 新用户名:新用户组 原文件用户cron任务莫名丢失删除用户时没注意cron删除前先crontab备份8. 实操经验与最后的一点建议这一整套流程走下来你会发现用户/用户组管理本身不算难真正难的是细枝末节的习惯。我个人在整个实操过程中踩过几次坑之后印象最深的几点分享给你第一账号命名和UID规划要超前。刚开始实验的时候随便建用户UID都是系统自动分配的1001、1002等到了要对接其他系统的时候就会发现“用户A在这台机器是1001在另一台机器是1005”文件同步过去全部乱套。比较好的习惯是重要用户手动指定UID比如useradd -u 1500这样保证多台机器之间的一致性。第二能用组解决的问题别用“改属主”解决。很多新手遇到“多人要访问一个目录”第一反应是把目录直接chown给某个人然后再给其他人开“其他用户”权限。这种做法是安全上的坏味道。正确路子永远是建一个组把目录设成组属主再把相关用户加进组。这样后续加人、减人只需要gpasswd -a/-d不需要再碰目录权限。第三所有批量操作都要留后路。无论是批量加组、批量删用户还是批量改密码脚本执行前的备份都是保命的一步。我已经习惯了每次批量操作前先把相关文件/etc/passwd、/etc/group、/etc/shadow、/etc/gshadow复制到一个带日期的备份目录里。备份成本极低恢复成本极高这笔账很容易算。第四权限管理要“最小够用”。给用户分配组时别图省事全塞进root组或者sudo组。一个用户只需要加入完成任务所需的最少组这是Linux下的第一安全准则。共享目录的权限也是同理目录权限给到rx即可让用户看加上写权限就要考虑“是不是所有人都需要往里写东西”。这篇内容属于“Linux入门到精通”系列的第3关它和后续的Linux文件权限、进程管理、用户审计等主题是连在一起的。第3关学的这些东西看起来基础但几乎所有中高级系统问题追根溯源都会触及用户/组的配置逻辑。如果你把这篇里讲到的实操全部在虚拟机里过了一遍并且理解了“用户/组改的是哪些文件、影响的是哪些权限”那你已经打好了很扎实的基础。接下来可以放心往前走比如自己试着配置一台新用户环境、搭建一个带共享目录的多人协作场景或者在策略里做更细的sudo权限拆分。系统管理的路就是拿命令堆出来的但每一条命令背后都有它的设计逻辑看明白了再动手才能走得远。