如果你用过一阵子Linux,肯定撞上过这种提示:Permission denied。发布环境里排查半天,最后发现是权限位少了一个x;或者写脚本时明明自己是root,创建出来的文件别人却读不了。我在某高校实验室做模拟项目X的时候,经常被这类问题绊住,后来索性把Linux命令与权限相关的知识点整理成了一套自测题,一边做题一边把底层逻辑补全,效果比死记命令好得多。
这篇文章不打算罗列一堆选择题答案,而是把题目背后的判断逻辑拆开讲,覆盖文件/目录权限差异、归属修改、chmod数字法与符号法、umask、SUID/SGID/Sticky Bit,以及常见的Permission denied排查路径。适合刚接触Linux的初学者,也适合正在准备运维或开发岗位面试、想把基础夯实的同学。
1. 权限位不是看懂rwx就完了,文件与目录的差异才是坑
这很反直觉:很多人以为文件权限set成777就万事大吉,可有时候目录权限不对,文件就算777也照样访问不了。这正是"Linux命令与权限选择题"里最容易出错的点。
1.1 文件上的r/w/x分别管什么
普通文件上,三个权限位对应三种操作:
| 权限位 | 作用 |
|---|---|
| r | 读取文件内容,比如cat、less能看到数据 |
| w | 修改文件内容,比如用编辑器写入并保存 |
| x | 将该文件作为程序或脚本执行,比如./run.sh |
需要注意,文件上的x权限只代表"系统允许把这个文件当作程序来调用",不代表"它一定是个可执行的程序"。比如一个文本文件,如果加了x权限,你执行它,大部分时候会报Exec format error或Permission denied(取决于解释器逻辑)。这个认知在选择题里经常被包装成"给脚本加了x就能运行",实际上是:脚本还需要正确的shebang行才行,x只是打开执行通道。
1.2 目录上的rwx才是最容易混淆的地方
目录的rwx和文件的含义完全不同,可以用生活类比来记:把目录想象成一栋楼的名单墙和门禁系统。
- r:允许列出目录内容,相当于能看到墙上的住户名单。但如果你没有x,光有r,你只看到"有这些文件名",却拿不到文件本身的任何信息或内容。
- w:允许在目录里创建、删除、重命名条目。注意,这个权限管控的是"目录条目",不是"文件内容"。只要你对目录有w权限,哪怕文件本身是只读的,你也能把它删掉或改名。这个点我在测试题里经常看到,很多人选错。
- x:允许进入目录并访问其中的文件,相当于楼的门禁卡。没有x,你连门都进不去,r和w都无从谈起。
所以,"对目录有r但没x"的表现是:你能用ls看到文件名列表,但用ls -l查看详细信息会报权限错误,cd进去更不可能。这是典型的选择题陷阱——r和x不是相互替代关系,而是"能看到名字"和"能真正进入"两码事。
1.3 组合权限的记忆口诀与实际操作
我在实际操作中习惯用一句口诀:文件看内容,目录看路径;进入靠x,改条目靠w。每次做题先判断对象是文件还是目录,再套这句,正确率能提上去一大截。
验证方法也很简单:
mkdir -p /tmp/demo_dir echo test > /tmp/demo_dir/a.txt chmod 444 /tmp/demo_dir ls /tmp/demo_dir cd /tmp/demo_dir你会看到ls能列出文件名,但cd会报Permission denied。再把目录改成555试试:
chmod 555 /tmp/demo_dir ls -l /tmp/demo_dir这次能进入,也能看到a.txt的详细属性。目录的x让路径访问通了,r让文件名列表可见。如果还需要在目录里创建文件,那就要w权限,此时目录应该是755或775之类的组合。
2. 归属三主体与归属修改:chown和chgrp的操作逻辑
权限位是针对"谁"生效的?这就引出了Linux权限模型中的三个主体:属主(user)、属组(group)、其他用户(other)。做题时,我见过太多人分不清"当前用户"与"文件属主"的关系,导致所有判断全错。
2.1 用id先搞清楚自己是哪一位
拿到任何权限题,第一步永远是先看自己是谁。id命令会输出用户的uid、gid以及附加组列表。比如某开发者在模拟项目X中常用:
id # uid=1001(alice) gid=1001(alice) groups=1001(alice),1002(dev)此时alice属于dev组。如果有一个文件的属组是dev,其他用户权限是r--,alice能不能读这个文件?能,因为alice的附加组包含dev,用组权限来判定。这是选择题里一个高频考点:可不要以为other就是"除了属主之外的所有人",组内的成员走的是group位,不是other位。
2.2 修改归属:chown与chgrp的正确用法
chown用于修改属主和属组,chgrp只修改属组。实际运维中,我经常看到有人把两者混用。规则如下:
chown alice file # 只改属主为alice chgrp dev file # 只改属组为dev chown alice:dev file # 同时改属主和属组 chown :dev file # 只改属组,等价于chgrp使用chown -R可以递归修改目录及其内部所有条目,但要注意符号链接:默认情况下chown不会追踪链接本身,而是修改链接指向的目标。想修改链接本身,需要加-h。这道细节在选择题中也会出现,比如"ln -s a b之后chown user b,a的内容属主变没变"——答案会变,因为b指向a。
2.3 为什么sudo不是万能钥匙
做权限题时,有人喜欢简单粗暴地加sudo,然后发现某些情况下sudo也访问不了文件。原因是sudo只是把你切换到root身份,但文件系统的挂载选项、SELinux策略、ACL都可能依然阻止访问。比如某目录挂载时加了noexec,就算你是root,在该目录里执行脚本照样报权限错误。
我在某跨平台系统的部署中就踩过这个:配置文件权限明明是644,可elasticsearch进程启动时一直报权限不够,最后发现是父目录的某个祖先路径是700,且属主是另一个用户。路径链上任一节点缺x,整个路径就断了。这个场景非常适合做成选择题:给出一长串路径,问哪个用户对target文件有读权限,结果在某个中间目录就被拦下。
3. chmod的数字法与符号法,以及umask如何影响默认权限
修改权限的命令是chmod,有两种用法:数字法和符号法。两者在考试和实际脚本里都常见,搞清楚本质就不会记混。
3.1 数字法的原理:rwx=421
数字法的本质就是二进制映射:r=4,w=2,x=1。把三者相加得到一个8进制数字,分别对应属主、属组、其他。比如755就是rwxr-xr-x,计算过程:
- 属主:r(4)+w(2)+x(1)=7
- 属组:r(4)+x(1)=5
- 其他:r(4)+x(1)=5
这个方法我不建议死记硬背,而是理解成"每个权限位是一个开关"。做题时,先把字母rwx转成数字,再把数字转回字母,两向都能熟练转换,选择题基本送分。比如4777是什么?这里4代表特殊权限SUID,后三位777是普通权限,合起来是rwsrwxrwx。这个考点放到特殊权限一节再细说。
3.2 符号法的使用场景
符号法用u(属主)、g(属组)、o(其他)、a(全部)加上+、-、=操作权限位:
chmod u+x script.sh # 给属主加执行权限 chmod g-w file # 去掉属组的写权限 chmod a=r file # 全部主体只保留r,清除w和x chmod u=rwx,g=rx,o=rx # 等效于755符号法在脚本里可读性更好,我写部署脚本时倾向于用符号法,因为它能明确表达"我要加什么"而不是"我要设成什么数字"。但在批量设置固定权限时,数字法更干脆。选择题里常见的问法是"以下哪个命令能给所有用户添加执行权限",答案chmod a+x比chmod 755更精准,因为755还会改到读写位。
3.3 umask:新建文件的默认权限是谁定的
umask是权限的一个"反掩码",它决定了新建文件和目录默认去掉哪些权限位。系统默认通常是022或002,含义是:
- 文件默认最大权限666,去掉022得到644,即rw-r--r--
- 目录默认最大权限777,去掉022得到755,即rwxr-xr-x
为什么文件默认没有x权限?因为马上创建一个可执行文件的场景太少了,系统默认不给x,防止误执行。需要x时手动chmod。umask里的每个数字也是8进制位,表示"要屏蔽的权限":
umask 027 touch testfile mkdir testdir ls -ld testfile testdir027屏蔽了组的写权限,以及其他的所有权限,结果文件是640,目录是750。我在实验室环境里喜欢把umask设置成027,防止同一台开发机上别的用户读走自己的密钥或脚本。
3.4 选择题里的umask典型陷阱
典型题目是:"某用户的umask是077,他touch一个文件后,该文件的权限是什么?"很多人会答成700,但正确答案是600。因为在Linux中,新建文件的基准权限是666,用666去除以8进制掩码——准确说是把666和077做"逐位减法":6-0=6,6-7=-1?这里其实是8进制下每位取掩码的反向逻辑,不能简单按十进制减。
更稳妥的计算方式是转成二进制思维:666是110 110 110,077是000 111 111,把这么理解:mask二进制位为1的地方,最终权限位被清0;为0的地方保留原值。所以:
666 110 110 110 077 000 111 111 结果 110 000 000 = 600这个"逐位清0"模型是我用过最不容易出错的理解方式,比背结论强太多了。目录同理,777按mask逐位清0:
777 111 111 111 077 000 111 111 结果 111 000 000 = 700所以目录默认权限才是700,这是和文件600的差异所在。做题多的人应该知道,umask这道题改一个词"目录"或"文件",答案就完全不同。
4. 特殊权限位:SUID、SGID、Sticky Bit不只是三个字母
普通权限讲完后,Linux还有三个特殊权限位,选择题和真实故障排查都喜欢考它们。我在某图像处理Demo的部署过程中,就因为一个SUID位丢了导致程序无法读取相关资源,排查了大半天,所以这里单开一节讲透。
4.1 SUID:为什么普通用户能改密码
SUID全称Set User ID,作用是在文件执行期间,把进程的有效用户ID切换为文件属主。最经典的例子是/usr/bin/passwd:
ls -l /usr/bin/passwd # -rwsr-xr-x 1 root root ...它属主是root,且有s标志。普通用户执行passwd时,进程临时以root身份运行,才能去写只有root能读写的/etc/shadow。如果这个SUID位被误删,普通用户改密码就会失败,这是实打实的排错场景。
用数字法设置SUID时,是在三位权限前加一个4:
chmod 4755 script # 等效于chmod u+s script选择题常考的坑是:owner位本来是rwx,设置SUID后,显示x变成了s(小写s);如果owner本身没有x权限,会显示大写S。大写S是一个"悬挂"状态:位已经设置,但因为属主没有执行权限,SUID功能实际不生效。这个细节我至少见过三道选择题围绕它出。
4.2 SGID:让协作目录自动继承属组
SGID用在目录上,会让该目录下新建的文件或子目录自动继承目录的属组,而不是创建者的主组。这在团队协作目录非常有用。设置方法:
chmod g+s /shared/project # 或者 chmod 2775 /shared/projectSGID位对应的数字是2。加了之后,文件显示为drwxrwsr-x。
实际操作时,某团队A同学创建完项目目录后,让组内所有人都能读写,但发现A同学创建的文件属组总是A的主组,其他成员只能读变更造成不便。后来设了SGID,就自动变成共享组了。这个"属组自动继承"的机制,在选择题里会以"在SGID目录下,新文件所属组是谁"的形式出现,答案不是当前用户,而是目录的属组。
4.3 Sticky Bit:/tmp目录的防删除机制
Sticky Bit(粘滞位)对应的数字是1,在other位的x位置显示为t。最典型的是/tmp目录:
ls -ld /tmp # drwxrwxrwt 20 root root .../tmp对所有人开放写权限,如果没有Sticky Bit,任何用户都能删除别人创建的临时文件。设了Sticky Bit后,只有文件属主、目录属主或root才有权删除或改名文件。这个机制对多用户共享目录非常关键。
设置方式:
chmod +t /shared/tmpdir # 或者 chmod 1777 /shared/tmpdir需要注意的是,Sticky Bit只对"删除/改名"有约束,不能阻止别人读取、甚至往文件里写入内容。如果文件本身是666权限,其他用户照样能打开编辑。选择题里经常用/tmp举例问"为什么在/tmp里不能删别人的文件",答案就是Sticky Bit在起作用。
4.4 特殊权限的踩坑现场
我见过的真实案例里,有人想给某个程序加SUID,随手执行了chmod 777 app,结果s位没有出现。原因很简单:777的三位数字本身不包含特殊权限位,要加SUID必须显式写4755或使用chmod u+s。数字法容易让人以为777就是个"全都开",实际上它只覆盖普通权限。
更隐蔽的坑是打包/解压导致的特殊权限丢失。tar解压时如果不加--preserve-permissions,SUID/SGID位可能全部被清掉,程序还能跑,但功能已经不正常了。我在某模拟项目X里遇到过:程序解压后正常启动,但普通用户一执行就报错,检查后发现SUID位没了。排查思路可以参考:
ls -l /path/to/app # 发现owner权限位是rwx而不是rws chmod 4755 /path/to/app5. 把知识点落回题目与排错:一组自测题与Permission denied排查链路
前面四节是底层原理,这一节回到标题里"选择题"本来的样子。做题不是为了把答案背下来,而是通过题目反推自己对原理有没有真正理解。
5.1 组自测选择题(附解析)
以下题目模式类似各种Linux权限选择题的常见变体,我把解析写出来,你可以先自己判断再看答案。
题目1:某文件权限为-rw-r-----,属主为alice,属组为dev,用户bob属于dev组,那么bob能读该文件吗?
解析:bob不是属主,但属于dev组,此时命中组权限r--,有r权限,可读。很多人会误判为"非属主就是other",但实际上只要用户在属组里,就优先走group位。other是"既不是属主,也不属于属组"的用户。
题目2:目录权限为d-wx------,属主alice。alice能ls该目录吗?
解析:目录权限:属主有w和x,但缺r。w可以创建/删除条目,x可以进入目录并访问已知路径的文件,但r缺失意味着无法列出目录内容。所以alice可以cd进去,只要知道文件名,也能cat某个文件,但ls会报错。这个结论很多人会答反,实际动手验证一次就记住了。
题目3:umask为022,创建一个新文件,权限是多少?
解析:文件基准666,用掩码逐位清0:0110 0110 0110,掩码000 010 010,结果0110 0100 0100,即644。记住目录和文件差一个x,这才是通常"为什么目录是755而文件是644"的原因。
5.2 从"Permission denied"反推权限问题
遇到运行时报权限错误,我建议按下面这个顺序排查,顺序错乱会浪费大量时间:
- 先确认当前身份:
id,搞清楚uid、gid、附加组。 - 再看目标对象的属主和属组:
ls -ln,注意-n能看到数字uid,避免用户名映射的误导。 - 分三段判定:目标路径上的每个目录都要有x权限;目标文件按属主/属组/其他逐级匹配;匹配顺序是"属主优先,其次属组,最后other",不是叠加关系。
- 检查特殊因素:ACL用
getfacl、挂载选项用mount | grep <path>、SELinux上下文用ls -Z。
这里有一个典型的排查案例。某跨平台系统部署后,应用日志目录一直写不进去,画面显示Permission denied。我按顺序排查:应用进程以service用户运行,日志目录属主是root,属组是root,权限是755。按常规逻辑,service用户是other,other有r-x,没有w,所以写不进去。解决方案是把目录属组改成service所在组并设置组写权限,或直接用chown改属主。
但还有一个隐蔽点:日志目录的父目录如果是700,service用户连进入的x权限都没有,那问题就不在日志目录本身,而在路径链上。我见过很多人卡在这,一直检查最后一级目录,却忘了看上一级。所以排查命令应该是:
namei -l /var/log/myapp/app.lognamei会逐级列出路径上每个组件的权限,权限断点一眼就能看清。这个命令在选择题里很少出现,但在真实排错中非常好用。
5.3 做题与排错之间的统一模型
如果把权限题和对Permission denied的排查放在一起看,会发现背后的模型是同一个:先确定主体身份,再找到匹配的权限位,最后检查特殊限制。选择题只是把这个过程简化成了纸上推演,而排错多了一步"用命令去获取事实"。
我建议读者在学这部分时不要只刷题,而是每次做题都顺手在终端里把场景搭出来。方法很简单:
useradd -m tester groupadd testgroup usermod -aG testgroup tester mkdir /tmp/perm_lab echo hello > /tmp/perm_lab/secret chmod 640 /tmp/perm_lab/secret chown root:testgroup /tmp/perm_lab/secret su - tester -c "cat /tmp/perm_lab/secret"这样每道选择题都变成了一次可复现的实验,理解了就不怕题目怎么变形。这个"题目变实验"的思路,是我从某导师那里学来的,后来在带新人时一直沿用,效果比单纯讲理论好很多。
我在实践中有一个体会:权限问题看起来琐碎,但它的底层逻辑非常整齐。无非是"我是谁、对象是谁、路径上每个节点让不让我过、有没有特殊限制"这几步。把这几步跑熟了,选择题基本不会错,线上问题也能快速定位。那些把权限玩得转的老手,不是背了更多命令,而是把判定模型内化成了肌肉记忆。你也可以试试用上面的方法,在终端里把每一类权限场景都亲手搭一遍——搭完以后,你会发现权限选择题真的就只是个选择题了。