news 2026/10/18 3:26:27

Linux用户管理实战:从/etc/passwd文件到正则匹配

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Linux用户管理实战:从/etc/passwd文件到正则匹配

我刚接触Linux那会儿,最喜欢翻的两个目录是/etc和/home。一个装着系统的"命根子"配置,一个装着所有用户的"小窝"。后来带过几个新人,发现大家最容易懵的也是这两个地方——尤其是/etc/passwd这个文件,乍一看就是一堆冒号分隔的乱码,但只要你搞懂了它,Linux的用户管理体系基本就通了半边天。这篇文章我就把第8集的内容串起来聊聊,从/etc目录讲到Shell切换,再到用户组管理和正则匹配,全是实操里反复用到的东西。

1. 从/etc目录谈起:先搞清"系统的灵魂目录"到底装了什么

1.1 为什么/etc值得你花时间仔细看一遍

/etc(ETCetera的缩写,意思是"等等其他")可以说是Linux系统里最重要的配置目录。你平时改IP地址、配DNS、设置开机自启、管理用户密码,最终落地的文件几乎都在这里。很多新手出问题,根子就在于不知道配置文件在哪、格式是什么、改完要不要重启服务。

我习惯把/etc下的文件分成三类:

  • 系统级配置:比如/etc/fstab(开机挂载分区)、/etc/hosts(本地域名解析)、/etc/resolv.conf(DNS配置)、/etc/sysctl.conf(内核参数)
  • 服务与应用配置:比如/etc/ssh/sshd_config、/etc/nginx/nginx.conf、/etc/crontab(定时任务)
  • 用户与认证信息:今天的主角/etc/passwd、/etc/shadow、/etc/group

其中用户管理这块,核心是三个文件:/etc/passwd存用户基本信息,/etc/shadow存加密后的密码和密码策略,/etc/group存用户组信息。这三个文件就是Linux用户体系的"台账",你用什么命令管理用户,本质上都是在改这几个文件的内容。

1.2 /etc/passwd的字段拆解:冒号分隔的"用户档案表"

/etc/passwd每一行代表一个用户,用冒号分成7个字段。比如我随便写一行:

dev_user:x:1001:1001:Dev User:/home/dev_user:/bin/bash

字段含义分别是:

字段位置含义示例值说明
1用户名dev_user登录时输入的名字
2密码占位符x真正密码在/etc/shadow里,这是安全机制
3UID1001用户ID,0是root,1-999通常是系统用户
4GID1001用户的主组ID
5注释信息Dev User一般是姓名或用途说明
6家目录/home/dev_user登录后的起始目录
7登录Shell/bin/bash登录后默认使用的Shell

刚学的时候有个问题很容易忽略:为什么密码字段是个x而不是一串加密字符串?早期Unix确实把加密密码直接放在这个文件里,但后来发现/etc/passwd是所有人都能读的,把密码哈希放这里等于公开了攻击样本。于是就把哈希挪到了只有root能读的/etc/shadow里,原位置留个x做标记。这个设计思路你品一品——权限最小化,能不给权限就不给权限。

2. Shell切换的几种姿势:chsh、$SHELL变量与登录Shell的关系

2.1 什么是登录Shell,它和终端里敲命令有什么区别

Shell就是你的命令解释器,你在终端里敲的每一行命令都是交给它执行的。Linux默认的Shell通常是bash,但也有很多人用zsh、fish。这里有个概念要分清:登录Shell和非登录Shell。

  • 登录Shell:你通过输入用户名密码登录系统时启动的Shell,它会加载/etc/profile和~/.bash_profile这类全局级配置
  • 非登录Shell:你在已登录环境里再开一个子Shell(比如在bash里直接敲bash),它主要加载~/.bashrc

这就导致一个经典问题:你改了~/.bashrc里的别名,重新登录后却"没生效"。其实不是没生效,而是登录Shell可能压根没读这个文件,或者其它配置文件把你的设置覆盖了。要确认当前Shell类型,可以看$SHELL变量和特殊变量$0:

echo $SHELL # 显示默认Shell路径,比如/bin/bash echo $0 # 显示当前正在运行的Shell,比如-bash/-zsh

2.2 chsh命令:永久切换默认Shell的正规方式

临时切换Shell很简单,直接敲对应的Shell名就行。但永久切换就要用chsh(change shell)了。新手最容易犯的错是直接改/etc/passwd里的最后一个字段,手一抖写错路径,下回登录直接进不去系统。用chsh能规避这个问题,因为它会帮你检查Shell路径是否合法(是否存在于/etc/shells里)。

chsh -s /bin/zsh

执行完会提示你输入密码,然后修改/etc/passwd里对应用户的Shell字段。改完重开终端生效,用echo $SHELL验证。注意,chsh只影响你当前登录用户,想改其他用户就得sudo chsh -s /bin/zsh 用户名。

这里有个实际工作中的场景:我有一台服务器,默认用/bin/sh的系统用户特别多,但某天需要给某个服务账号切到bash来执行脚本,当时就是用chsh -s /bin/bash 服务账号名完成的。改之前务必确认目标Shell已经装好了,不然容易出现"服务启动不了,日志里报错找不到解释器"的情况。

2.3 /etc/shells的限制:为什么有些Shell路径会被拒绝

刚才提到/etc/shells,这个文件里列出了系统认可的所有Shell路径。chsh会检查你指定的Shell是否在这个列表里,不在就报错。设计这个机制的目的是防止你把登录Shell改成一些奇怪的程序,比如改成/bin/ls,那用户一登录看到的不是提示符而是一堆文件列表。所以当你编译安装了新Shell(比如从源码安装zsh到/usr/local/bin/zsh),记得先把它加进/etc/shells再chsh。

提示:修改/etc/shells要root权限,加一行/usr/local/bin/zsh,之后再执行chsh -s /usr/local/bin/zsh就顺了。

3. 用户与组管理:从useradd到usermod的完整实操链路

3.1 useradd的默认行为:为什么新建用户后没有家目录

useradd是创建用户的命令,但很多人上来就踩坑——新建完用户,用su切过去发现提示"no directory",这才意识到没建家目录。原因在于不同发行版的useradd默认行为不一样。有些系统默认不创建家目录,你需要显式加-m参数:

sudo useradd -m -s /bin/bash dev_user

这条命令同时做了三件事:创建名为dev_user的用户,给它建家目录/home/dev_user,指定登录Shell为/bin/bash。如果你还想指定UID/GID,可以用-u和-g:

sudo useradd -m -u 1500 -g dev_group -s /bin/bash dev_user

这里的-g指定的是主组(primary group),后面还能用-G指定附加组(supplementary group)。主组决定用户创建文件时默认的组归属,附加组决定用户额外拥有哪些组的权限。两者别搞混,实际运维里因为主组和附加组搞混导致权限无法预期的例子非常多。

3.2 /etc/default/useradd和/etc/login.defs:改默认配置比每次敲参数更省事

如果你嫌每次创建用户都要敲一堆参数,可以去改两个配置文件:

  • /etc/default/useradd:定义默认家目录路径、默认Shell、默认的SKEL目录(新家目录的模板来源)
  • /etc/login.defs:定义UID/GID范围、密码过期策略、创建家目录的默认行为

比如login.defs里有一项CREATE_HOME,有些版本设成no,这就是新建用户没有家目录的直接原因。改成yes就能让所有新用户默认有家目录,不用每条命令都加-m。

3.3 usermod:用户信息调整的"瑞士军刀"

用户建好之后,调整信息就靠usermod。它的用法和useradd几乎一致,只是把"创建"变成"修改":

sudo usermod -l new_name dev_user # 改用户名 sudo usermod -u 2000 dev_user # 改UID sudo usermod -g dev_group dev_user # 改主组 sudo usermod -aG docker dev_user # 把用户加入docker组(-a必须加,否则会被移除原有附加组)

-aG里的-a(append)特别关键。很多人在改附加组时忘记加-a,结果用户从其他组里被"踢"出来了。我有一次就是把一个用户从sudo组里踢了,对方半天登录不了管理后台,排查了一会儿才发现是-G覆盖了原有组。记住:修改附加组永远带上-a。

3.4 userdel:删除用户没那么简单

删除用户用userdel,但单纯执行userdel 用户名可能留下家目录和邮件目录。所以推荐用-r参数:

sudo userdel -r dev_user

这个-r会同时删除用户的家目录和邮件池,干净利落。不过有个细节要注意:如果被删除的UID还被文件占用(比如某个文件属主是这个UID,但用户名已经删了),那些文件就会显示成无主文件的数字ID。所以删除前最好先find / -user dev_user扫一下,确认没有重要文件再动手。

3.5 groupadd和groupdel:组管理的基本操作

组就是用户的集合,用groupadd创建、groupdel删除:

sudo groupadd dev_group sudo groupadd -g 2000 dev_group # 指定GID sudo groupdel dev_group

删除组之前要确认组里没有用户的主组指向它,否则报错。实际操作中遇到这种报错,得先用usermod -g把相关用户的主组改掉,再来删组。查看用户属于哪些组,用id命令或groups命令:

id dev_user groups dev_user

groups输出的是用户所属的所有组,但注意它直接读/etc/group,所以即时生效。而id显示的信息更全,包括UID/GID和所有附加组,排查问题我推荐id。

4. passwd命令的隐藏技能与密码安全实操

4.1 修改密码的基本操作和权限边界

平时我们用passwd改自己的密码,root能改任何人的密码。这里说几个不那么"新手友好"的用法:

passwd # 改当前用户密码 sudo passwd dev_user # root强制改指定用户的密码 sudo passwd -l dev_user # 锁定账号(Lock) sudo passwd -u dev_user # 解锁账号(Unlock) sudo passwd -e dev_user # 强制用户下次登录时改密码(Expire) sudo passwd -n 7 -x 90 dev_user # 设置密码最短使用7天,最长90天

-e这个参数在实际运维里非常有用。比如你给某个新员工开通账号,初始密码设置完之后执行passwd -e,对方第一次登录就被逼着改密码,避免长期使用连你自己都知道的初始密码。

4.2 /etc/shadow里那些冒号字段到底什么意思

/etc/shadow也被冒号分隔,但字段更多,核心是这几项:

dev_user:$6$xxxx...:19000:7:90:7:30::
字段含义说明
1用户名对应/etc/passwd
2密码哈希$6$开头是SHA-512算法
3最后一次修改密码的时间从1970-01-01起的天数
4密码最短使用天数0表示随时可改
5密码最长使用天数99999表示永不过期
6过期前警告天数7表示提前7天提醒
7宽限天数密码过期后还能登录的天数
8账号失效时间空表示永不失效
9保留字段一般空着

看懂这个文件,你就能解释很多"灵异现象"。比如某天用户突然登录不了,提示密码过期,那多半是第5字段设了有效期,时间到了;又比如账号明明被锁了,手动改/etc/shadow把密码字段前面加个!即可锁号,passwd -l做得也是类似的事。

4.3 批量处理密码:chpasswd和expect场景

如果有几十个测试用户要统一设密码,别一个个passwd,用chpasswd:

echo "dev_user:NewPass123" | sudo chpasswd

还可以配合文件批量处理:sudo chpasswd < users.txt,文件格式同样是用户名:密码,一行一个。这个命令在自动化脚本里尤其顺手,但注意密码会出现在命令行历史里,自己机器玩玩没问题,生产环境建议配合密钥登录,少用明文密码传递。

5. 正则表达式:用户管理场景下的实用匹配技巧

5.1 为什么学用户管理一定要碰正则

前面提到的/etc/passwd、/etc/group都是文本文件,既然管理用户最终都是操作文本,那就免不了要用正则去搜索、过滤、统计。举个最常见的场景:我想找出所有UID大于1000的普通用户,用grep加正则一条命令搞定:

grep -E '^[^:]+:[^:]+:(1[0-9]{3,}|[2-9][0-9]{3,}):' /etc/passwd

这个正则的意思拆开看:^[^:]+匹配行首连续非冒号字符(用户名),[^:]+匹配密码字段,(1[0-9]{3,}|[2-9][0-9]{3,})匹配1000以上的数字(要么1000-1999,要么2000以上)。如果不用正则,你得先cat /etc/passwd再肉眼找,用户一多就废了。

5.2 grep、egrep和正则符号速记

先分清grep和egrep(等价于grep -E):egrep支持扩展正则,可以直接用+、?、|、{}这些高级符号,普通grep需要用反斜杠转义才能用,麻烦还容易错。建议日常统一用grep -E。

几个高频符号:

符号含义示例
^行首^dev匹配以dev开头的行
$行尾bash$匹配以bash结尾的行
.任意单个字符a.c匹配abc/adc
*前一个字符重复0次或多次ab*c匹配ac/abbc
+前一个字符重复1次或多次ab+c匹配abc/abbc但不匹配ac
[]字符集[Dd]ev匹配Dev或dev
[^]排除字符集[^:]匹配任意非冒号字符
|或dev|test匹配dev或test
{n,m}重复次数范围[0-9]{3,}匹配3位以上数字
()分组(ab)+匹配ab/abab

5.3 实际案例:用正则筛选需要清理的僵尸账号

我前阵子接手一台服务器,需要盘点哪些账号是"垃圾账号"。当时用了几条正则命令做筛选:

先找出所有登录Shell是/usr/sbin/nologin的账号,这些一般是服务账号,不能登录shell,按理说不用清理:

grep -E '/usr/sbin/nologin$' /etc/passwd

再找出所有家目录在/home下但已经半年没登录的账号。登录时间得去lastlog看,所以用lastlog配合awk处理:

lastlog -t 180 | awk '{print $1}' | grep -v -E '^(Username|root)$'

这里的-v是反向匹配,排除表头和root。正则里^Username$精确匹配整行。最后用usermod把确认不用的账号锁掉:

sudo usermod -L 用户名

整个过程下来,正则不是炫技,而是把文本处理的效率拉满。你想精准操作文本,正则绕不过去。

5.4 正则的常见陷阱:贪婪匹配和转义问题

新手写正则最容易踩两个坑。

第一个是贪婪匹配。默认情况下*和+是贪婪的,会匹配尽可能多的字符。比如你用^a.*:匹配abc:def:,它会匹配到最后一个冒号,而不是第一个。想改成非贪婪,在*或+后面加?(但要注意,这个语法在grep -E里不一定支持,得看版本)。实战中我通常宁可把正则写得"窄"一点,也懒得和贪婪较劲。

第二个是转义。在/etc/passwd里冒号是分隔符,你想匹配冒号本身没问题,但如果你想匹配[或]这种正则符号,就得加反斜杠转义。比如grep -E '\[root\]' /etc/passwd匹配字面上的[root]字符串。很多人在这里反复试错,其实记住一点就行:你想匹配的字符碰巧是正则元字符,那就加\让它变回普通字符。

6. 把这套知识串起来:一个从零创建用户到配置环境的完整示例

光讲命令太散了,我带你把今天的内容串成一个真实场景。假设我现在要给一个来自某高校实验室的协作者开一个账号,名字叫lab_user,让他能用bash、能自己装软件(把他加进sudo组),同时限制密码90天过期。完整操作如下:

# 1. 创建用户并指定家目录和Shell sudo useradd -m -s /bin/bash -c "Lab Collaborator" lab_user # 2. 设置初始密码,并强制首次登录修改 echo "lab_user:TempPass2024" | sudo chpasswd sudo passwd -e lab_user # 3. 将用户加入sudo附加组 sudo usermod -aG sudo lab_user # 4. 验证用户信息 id lab_user grep -E '^lab_user:' /etc/passwd

这条链路跑完之后,grep查到的结果就是一条标准的/etc/passwd记录。如果后续要删除这个账号,一个sudo userdel -r lab_user就能收尾。这里再提醒一下,userdel -r会删家目录,当心客户数据。

再看一个自动化场景。某次我需要给模拟项目X的20个临时用户批量重置密码,密码统一为随机生成的串,然后强制所有人下次改密码:

for u in $(cat user_list.txt); do echo "$u:$(openssl rand -base64 12)" | sudo chpasswd sudo passwd -e "$u" done

这里用了openssl rand生成随机密码,chpasswd批量写入,最后强制过期。你看看,这几条命令背后全都是今天讲的文件、命令和正则思路。

7. 踩坑记录:用户管理里的三个典型翻车现场

写到最后,我把自己见过(也踩过)的几个坑列出来。这些内容正经文档里很少细讲,但实际运维碰到的概率很高。

第一个坑:手动改/etc/passwd导致系统登录崩溃。有一次图省事,我直接用vim给某个用户的家目录路径加了个字,结果多打了一个字母。用户那边完全登录不进去。后来用系统修复模式进去改回来的。所以改用户信息老老实实用usermod,别手搓/etc/passwd。如果非要手改,先把/etc/passwd备份一份:cp /etc/passwd /etc/passwd.bak。

第二个坑:usermod -G把用户从sudo组踢出。这个前面已经提过,但我愿意再说一次,因为太典型了。当时我想把一个用户加入docker组,用的是sudo usermod -G docker 用户名,忘了加-a,结果sudo组没了。幸亏机器上还有其他管理员账号,local console还能救。教训就是:写进肌肉记忆,附加组操作永远-aG。

第三个坑:正则写错导致批量锁定账号。之前写清理脚本,打算锁掉所有登录Shell为/bin/false的用户,正则写成了grep -E '/bin/false' /etc/passwd,结果把注释信息里带有"false"字样的用户也匹配进去了。幸好锁的是几位同事的测试号,被念叨了好几天。从那以后我写这种批量操作,都会先跑一遍grep单独查看匹配结果,确认无误后再接usermod。宁可多敲一条命令,也别批量误伤。

8. 收尾:一点实际使用后的体会

这套内容学完之后,我建议你把重点放在"文件-命令-正则"三者之间的关系上。命令记住了只能解决眼前事,理解了/etc/passwd、/etc/shadow、/etc/group这几个文件的结构和字段含义,遇到任何用户异常你都能顺着文本文件找到根因。正则更是给效率加buff的工具,别怕写错,多多debug,自然就熟练了。

后面我还会继续更新Linux基础系列的后续内容,比如文件权限的深入剖析、环境变量加载顺序、systemd管理服务之类的。如果这篇文章对你有点帮助,欢迎在评论区聊聊你踩过的用户管理相关的坑,我每条都会看。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/18 3:25:29

onclick与ondblclick冲突:从事件原理到防重复方案

1. onclick 和 ondblclick&#xff1a;这两个鼠标事件到底在干什么最早在业务里碰到 onclick 和 ondblclick&#xff0c;是在一个后台管理表格上。功能本身不复杂&#xff1a;单击某一行的某列时做高亮&#xff0c;双击时才进入编辑。等真正做完&#xff0c;我才发现这对事件天…

作者头像 李华
网站建设 2026/10/18 3:23:50

Scala流式解析DBpedia RDF:Neo4j图数据库导入实战

简介&#xff1a;这份资源面向需要将 DBpedia 知识图谱导入 Neo4j 图数据库的开发者与数据工程学习者&#xff0c;核心是一个用 Scala 编写的 Spark 应用程序&#xff0c;可将 DBpedia.org 的平面文件 RDF 转储处理并生成 CSV&#xff0c;进而构建 Neo4j 数据存储文件&#xff…

作者头像 李华
网站建设 2026/10/18 3:19:55

UE5 Nanite+SpeedTree 10:告别纸片树冠,打造真实体积植被

做了这么多年环境美术&#xff0c;我最怕在评审的时候听到一句话&#xff1a;“这棵树看起来像纸片。”树冠一旦“纸片化”&#xff0c;不管上面叠了多少张法线贴图、多少层细节纹理&#xff0c;整个场景的可信度都会立刻崩掉。过去我们靠交叉面片&#xff08;card&#xff09;…

作者头像 李华
网站建设 2026/10/18 3:16:09

防火墙安全区域划分与策略配置:模拟器实操入门指南

1. 为什么要在模拟器里折腾防火墙区域划分很多人第一次接触企业级防火墙&#xff0c;都是在模拟器里点开一台设备&#xff0c;看到满屏的security-zone、firewall packet-filter之类的命令&#xff0c;然后就开始犯迷糊&#xff1a;明明交换机路由器配得好好的&#xff0c;怎么…

作者头像 李华
网站建设 2026/10/18 3:15:35

金融大模型规模化落地:消金行业实践与关键技术选型

金融大模型已经从“能不能跑”过渡到了“怎么规模化跑”的阶段。消金行业对成本和效率极度敏感&#xff0c;历来是新技术落地的试验田&#xff0c;大模型当然也不例外。我花了几个月时间调研走访了几家走在前面的机构&#xff0c;也亲自下场参与了两个项目的方案设计&#xff0…

作者头像 李华
网站建设 2026/10/18 3:05:55

计算机网络面试笔试高频考点全解析:从TCP/IP到HTTP/HTTPS

最近好几个朋友在准备大厂和中小厂的校招、社招面试&#xff0c;不约而同卡在计算机网络这一块。说复习不知道从哪下手&#xff0c;说背题又觉得八股文太多记不住&#xff0c;笔试里稍微换个问法就懵。计算机网络面试笔试基础知识&#xff0c;听起来像是“背背书就能过”的内容…

作者头像 李华