资讯动态

Linux权限管理从ls -l到chmod/chown:文件类型、rwx与特殊位全解析

发布时间:2026/10/15 14:36:23 来源:尧图企业网站定制
刚接触 Linux 那会儿我对着ls -l的输出发过呆-rw-r--r--、drwxr-xr-x这到底是爻卦还是乱码后来写 Shell 脚本又频繁遇到[ -d /data ]、[ -s file.log ]这种判断当时照着同事的代码抄能用就行压根没深究。直到有一次脚本判断目录的逻辑出了 bug排查半天发现是-d在不同命令里含义不一样才痛下决心把这一串东西彻底搞明白。这篇就把-d、-s这些容易混的参数讲透顺着ls -l的第一列把文件类型、属主属组、rwx 权限、SUID/SGID 特殊位全部串起来。适合刚入门 Linux 的运维新手、经常写脚本的开发同学也适合所有被 Permission denied 折磨过的人。1. 先分清-d 和 -s 是谁家的参数1.1 在 test 和 [ ] 里-d 是判断目录-s 是判断非空这是最常见、也最容易先入为主的一个场景。test是 Shell 内置的判断命令[ ]是它的同义写法本质完全一样。在脚本里你经常会看到if [ -d /var/log ]; then echo 目录存在 fi-d在这里的意思就是后面的路径存在并且是一个目录。注意它同时包含了两层判断路径得存在而且类型必须是目录。如果路径不存在或者它是个普通文件这个判断都会返回假。if [ -s /etc/passwd ]; then echo 文件存在且非空 fi-s的判断是文件存在而且大小大于 0 字节。一个常见坑是新建的空文件比如touch出来的用-s判断会返回假因为文件内容为空。这在判断日志文件有没有写东西、配置文件是否被清空时非常有用。test 常用的文件判断选项选项判断内容典型用途-e路径存在不管类型判断文件或目录是否在-f存在且是普通文件区分文件和目录-d存在且是目录判断目录-s存在且文件大小大于 0判断空文件-r/-w/-x当前用户是否可读/可写/可执行权限预检-L存在且是符号链接判断软链这里有个容易忽略的点-r、-w、-x判断的是调用 test 的当前用户是否具备对应权限而不是文件自身权限字符串写得有多宽松。也就是说[ -w file ]返回真假取决于你当前是谁而不是ls -l里的输出。我见过不少人用ls -l一看有-rw-r--r--就觉得能写结果自己是 other 角色照样写不进去。1.2 在 ls 里-d 是目录本身-s 是磁盘块占用test里的那套含义到了ls命令里完全不灵。ls -d的意思是只列出目录本身不展开目录内容。ls -d */ # 只看当前目录下有哪些子目录注意*/后面那个星号它会匹配所有子目录但如果你不加-dls会把匹配到的目录里的内容都列出来输出会非常乱。加了-d它只显示目录名。这个写法在脚本里想快速拿到当前目录下所有子目录列表时特别实用。ls -s则是指示ls输出文件占用的磁盘块数ls -s /var/log输出的第一列数字就是占用的块数不是字节数。块大小跟文件系统有关常见是 4K 或 1K。想看到更直观的大小用ls -lh看人性化的 KB/MB 输出比-s更常用。这里想强调的是不要背某个选项在 Linux 里是什么意思而要问这个选项在哪个命令里。同一个-d在tar里可能是另一种语义在grep里又可能是别的用途——Linux 的选项从来不是全局统一的这一点想清楚后面能少走很多弯路。1.3 在 ls -l 的输出里d 和 s 是状态标记如果你运行过ls -l会看到输出第一列是一串像drwxr-xr-x这样的字符。这里的d不再是任何命令选项而是文件类型的标记d表示这是一个目录directory。后面跟着的九个字符里有时候还会出现s比如-rwsr-xr-x那个s是特殊权限位的标记跟普通的 rwx 完全不是一回事。也就是说同一个字符d和s在test里、在ls选项里、在ls -l的输出串里分别代表三种完全不同的概念。这是新手最容易懵的地方也是本文要重点拆解的起点。接下来我们就从ls -l的第一列开始把这串字符的每一位都讲清楚。2. 把 ls -l 第一列拆到骨头里2.1 第一个字符决定文件类型ls -l输出的第一列总共 10 个字符。先看第一个字符它标识文件类型字符类型举例-普通文件文本、二进制、压缩包d目录各种文件夹l符号链接软链如/etc/xxx - /usr/...c字符设备/dev/tty等b块设备/dev/sda等硬盘p命名管道进程间通信ssocket网络通信节点大多数时候你只需要记住-、d、l三种。判断一个路径是文件还是目录最稳的不是看扩展名而是看这个第一个字符。在脚本里可以用[ -f ]和[ -d ]判断人眼识别最快的方式就是看ls -l的这一位。2.2 九个 rwx 位分给三种角色第一个字符之后还有九个字符每三个一组分别代表属主user、属组group、**其他人others**的权限-rwxr-xr-x ↑ ↑ ↑ u g o第一组文件属主owner的权限第二组文件属组group内成员共有的权限第三组既不是属主、也不属于属组的其他人的权限每一组里三个字符的位置固定是r读、w写、x执行。该位有权限就显示对应字母没有权限就显示-。比如-rw-r--r--属主可读可写rw-属组只读r--其他人只读r--。这就是最常见的文本文件权限也是chmod 644的效果。注意九个字符里如果出现s或t它们不是普通的 rwx而是占了x位显示的特殊权限标记后面会专门讲。现在先把ls -l整行读完再回来说特殊位。2.3 目录权限的 rwx 和文件完全是两回事很多人把目录当成装文件的容器于是顺手用文件那套逻辑去理解目录权限结果到处碰壁。目录的 rwx 含义得重新定义r读目录允许列出目录下有哪些名字也就是ls这个目录时能看到文件名。w写目录允许在目录里创建、删除、重命名文件或子目录。x执行目录允许进入这个目录也就是cd进去以及访问目录内文件的属性。这里最关键的是x。一个目录如果只有r没有x你可以ls看到文件名但cd不进去也没法读取文件内容反过来只有x没有r你能进去但看不到目录里有什么名字只能凭已知的文件名访问。所以实际运维里目录几乎都要给x常见组合是755属主全部属组和其他人只读执行或者750属组其他成员不能读。理解这一点之后很多怪问题就通了。比如你有一个文件权限是-rw-r--r--属主也是你但你就是打不开很可能是因为文件所在目录的某一层没有x权限你根本进不了那个目录路径。2.4 顺手把 ls -l 整行信息读通ls -l的一行完整输出是这样的-rw-r--r-- 1 alice devops 2048 Feb 20 10:30 report.txt除了第一列的 10 个字符后面还有这些信息1硬链接数。普通文件通常是 1目录至少是 2自身和.。alice文件属主。devops文件属组。2048文件大小单位是字节目录显示的是元数据大小而不是内容总大小。Feb 20 10:30最后修改时间。report.txt文件名。把属主和属组单独拎出来看是有意义的。属主是谁拥有这个文件属组是哪一群人共享这组权限其他是剩下的所有人。后面要讲的 chown 和 chgrp改的就是这两列。而 chmod 改的是第一列的权限位。三者经常被混在一起说但实际上管的是不同维度chown 改身份、chmod 改权限身份和权限是两个独立的东西。3. chmod 修改 rwx 权限的两种姿势3.1 符号模式ux、g-w、or 怎么写chmod是修改权限的核心命令有两种写法。第一种是符号模式用字母组合来表达给谁、加什么、加哪个权限。基本结构是chmod [谁][操作][权限] 文件谁u属主、g属组、o其他、a全部相当于 ugo操作加、-减、设置成精确的值权限r、w、x几个常用例子chmod ux script.sh # 给属主加执行权限 chmod g-w report.txt # 去掉属组的写权限 chmod or report.txt # 其他人的权限设置为只读原来的权限全被覆盖 chmod ar report.txt # 三种角色都加读权限 chmod urwx,grx,orx file # 一次精确设置属主 rwx属组 rx其他 rx符号模式的好处是只动你想动的部分比如chmod ux不会碰其他位的权限。写脚本或临时调权限时我习惯用符号模式直观、不容易出错。3.2 数字模式rwx 就是三位二进制第二种是数字模式也是新人最怕但老手最爱用的。其实原理非常简单每一组 rwx 的权限位本质上就是三位二进制数有权限是 1没权限是 0。r w x 1 1 1 7 1 0 1 5 1 0 0 4 0 0 0 0所以r4、w2、x1加在一起就是 7。rwxr-xr--拆成三组就是 7、5、4也就是chmod 754。chmod 755 script.sh # rwxr-xr-x脚本常见权限 chmod 644 report.txt # rw-r--r--文本文件常见权限 chmod 600 id_rsa # rw-------私钥必须这么设 chmod 700 ~/.ssh # drwx------私有目录 chmod 664 shared.json # rw-rw-r--同组协作写几个高频组合直接背权限含义用途600rw-------私钥、敏感配置文件644rw-r--r--普通文件700rwx------私有目录/脚本755rwxr-xr-x可执行文件、网站目录775rwxrwxr-x同组协作目录777rwxrwxrwx谁都随便改慎用我个人是这么记的数字模式适合把整个权限一次性设置成目标状态符号模式适合在现有权限上小修小补。两者不冲突看场景选用。3.3 递归改权限的推荐做法如果目录里有一堆文件和子目录需要整体调整权限很多人第一反应是chmod -R 755 /data/app这个命令确实能递归改但有个隐患目录和文件的权限需求经常不一样。目录需要x以便进入普通文件通常不需要执行权限。chmod -R 755会把所有普通文件也加上执行位虽然不致命但在一些安全要求严格的场景会被审计挑出来。我推荐的做法是分开处理find /data/app -type d -exec chmod 755 {} \; find /data/app -type f -exec chmod 644 {} \;先对目录统一755再对普通文件统一644这样每个对象拿到的权限都符合常规预期。这个组合命令值得抄进自己的小本本部署场景里几乎天天用。3.4 默认权限由 umask 决定你有没有好奇过明明没有手动设置新建的文件为什么默认是644新建的目录默认是755答案在umask。新建文件的基准权限是666因为文件默认不带执行位新建目录的基准权限是777。umask的作用是从基准权限里扣掉某些位。当前用户的 umask 可以用umask命令查看常见值是022umask # 022666 - 022 644777 - 022 755这就是默认权限的来源。如果改成002新建文件就是664新建目录就是775适合多人协作的场景因为同组成员默认就有写权限。这个知识在排查为什么别人创建的文件权限跟我不一样时很有用也可能是公司安全策略的一部分。想临时改直接umask 002想永久改写到用户的 shell 配置里。4. chown 和 chgrp给文件换主人4.1 chown 的三种常见用法chown 改的是文件的属主和属组。很多服务部署出问题回头看都是属主搞错了。先看基础用法sudo chown alice report.txt这是把report.txt的属主改成alice属组不变。注意修改属主一般需要 root 权限普通用户不能把文件送给别人这符合设计逻辑如果谁都能把文件改成 root 属主那权限体系就形同虚设了。sudo chown alice:devops report.txt同时改属主和属组冒号前面是用户后面是组。这种一次性写全的写法最清晰推荐默认使用。sudo chown :devops report.txt冒号前面留空表示只改属组等价于 chgrp。写脚本时这个写法比单独调用 chgrp 少敲一个命令。4.2 chgrp 单独修改属组如果你只想改属组也可以明确用chgrpsudo chgrp devops report.txtchgrp比 chown 更语义化团队协作时把某个目录的属组交给项目组chgrp -R devops /data/project一下搞定。关于组可以顺带理解一下每个用户除了自己的用户名还属于一个或多个组。用id命令查看自己属于哪些组。文件的属组决定了组内所有成员对它的权限这是 Linux 多用户权限模型里很重要的一环。有一个容易混淆的点修改属组一般是文件属主自己就能做的只要你是属主且属于目标组成员但修改属主通常必须 root。这个差异知道就好实际操作中大家基本都用 sudo。4.3 递归修改归属时的注意事项服务目录或数据目录整体换主人要用-R递归sudo chown -R alice:devops /data/app递归修改会层层遍历把目录下所有文件和子目录都改掉。这里有个经验先确认好范围再执行。我见过一次事故某同事执行chown -R时路径少打了一个字母把上级目录的所有权也改了整个应用的账号体系当场乱套。执行前建议先ls -ld看清楚目标路径再跑命令。另外如果目录里有符号链接普通chown -R默认不会跟着链接跳转只会改链接本身。在 GNU 环境里chown -hR可以控制是否操作链接指向的目标。实际使用中少用-hR去穿透链接避免误伤。4.4 --reference 参照修改有时你希望让这个文件的属主属组跟另一个文件一模一样可以不用一个个查再敲直接用参照模式sudo chown --referencetemplate.txt target.txt这个命令把target.txt的属主和属组设置成与template.txt一致。批量迁移文件时特别好用比如从旧服务器同步了一堆文件过来想统一对齐到某个基准文件的属主属组一条命令搞定不需要去翻每个文件的原始属主。chmod同样支持--reference用法一致。5. 特殊权限位文件权限里真正的隐藏关卡5.1 SUID带着主人身份去执行普通 rwx 之外Linux 还有三个特殊权限位它们就藏在 rwx 字符串里显示时常被忽略。第一个是 SUIDSet User ID。找个经典例子ls -l /usr/bin/passwd # -rwsr-xr-x ... /usr/bin/passwd注意属主那一组rws而不是rwx这里的s占据了x的位置。这个s表示passwd 程序带着文件属主root的身份去执行。也就是说普通用户运行passwd时这个进程临时拥有 root 权限能去写只有 root 能改的/etc/shadow。改完密码退出权限就回收了。SUID 的设计目的是让普通用户完成需要特权才能做的任务但它也是安全风险的高发点。如果某个可写文件被设置成 SUID 且属主是 root任何用户运行它都能拿到 root 身份这就成了提权漏洞。所以排查服务器安全时第一条命令就是找全盘 SUID 文件find / -perm -4000 -type f 2/dev/null-4000表示匹配带 SUID 位的文件。如果你发现某个不该有 SUID 的二进制带了这个位尽早处理。5.2 SGID目录级继承组第二个特殊位是 SGIDSet Group ID。文件带了 SGID运行时会带着文件属组的身份去执行跟 SUID 同理。但 SGID 更常见的价值体现在目录上。给目录设置 SGID 后sudo chmod gs /data/shared ls -ld /data/shared # drwxrwsr-x ...之后在这个目录里新建的文件或子目录其属组会自动继承目录的属组而不是创建者自己的主组。这对团队协作是个神器不管谁往里放文件文件都被归到项目组名下组内成员默认可以读写再也不用每次手动 chgrp。注意新建的子目录也会继承 SGID继续往下传播。所以一个项目共享目录配上chmod -R gs再加上chmod -R 2775基本就是一套省心的协作权限方案。5.3 粘滞位/tmp 里为什么别人删不了你的文件第三个特殊位是粘滞位Sticky Bit。最典型的例子是/tmpls -ld /tmp # drwxrwxrwt ...最后一位t就是粘滞位。它的作用在一个所有用户都能写入的目录里比如/tmp权限是777粘滞位限制了删除行为——只有文件的属主以及 root才能删除或重命名这个目录里的文件其他用户即使对目录有写权限也动不了别人的文件。没有粘滞位会怎样目录是777、可写任何用户都能删掉别人的临时文件这显然没法接受。所以公共临时目录几乎都带t。自己搭共享目录时如果希望大家都能放文件但只能删自己的就给目录设粘滞位sudo chmod t /data/upload5.4 特殊位的设置、取消与数字写法特殊位同样可以用chmod设置和取消chmod us file # 设置 SUID chmod u-s file # 取消 SUID chmod gs dir # 设置 SGID chmod g-s dir # 取消 SGID chmod t dir # 设置粘滞位 chmod -t dir # 取消粘滞位数字模式下特殊位占在权限三位数的前面形成四位数SUID 对应 4SGID 对应 2粘滞位对应 1所以chmod 4755表示 SUID 755chmod 2755表示 SGID 755chmod 1777表示粘滞位 777。四个数字一起写的场景很少但至少要会读看到4755、2775、1777要能立刻反应出它带了哪个特殊位。一个容易看错的细节ls -l里的小写s和t表示特殊位和x同时存在如果特殊位存在但x不存在显示的是大写S或T比如-rwSr--r--。看到大写别慌它只是提示特殊位有了但执行位没有绝大多数情况下这不是你想要的配置检查一下是否设置错了。6. 权限和属主问题排查的几条实战心得6.1 服务起不来先用 id 和 stat 看身份遇到启动服务报 Permission denied我现在的排查顺序是先看服务进程是以哪个用户运行的看服务配置或启动脚本再用id确认这个用户的组用stat查看报错文件的属主、属组和权限id stat /path/to/problem/file大多数时候问题不是权限位不对而是身份不对——比如文件属主是 root服务却用普通用户跑普通用户当然进不去。先确认身份再去改 chown 或 chmod比一上来就chmod 777靠谱得多。6.2 有写权限却删不掉文件先看粘滞位目录是 777我也有写权限为什么删不掉里面的文件这个问题我回答过好几轮。十有八九是目录带粘滞位。前面说过粘滞位的作用就是只有文件属主才能删。如果你在一个共享目录里想删别人创建的临时文件即使你有写权限也会被拒绝。解决办法不是硬删而是找文件属主删或者用 root 身份操作。这也是很多临时上传目录的标准安全配置不是 bug别去 chmod 掉t。6.3 路径中任意一级目录没有 x 权限都会报错访问一个文件的完整路径比如/var/www/html/index.html内核要逐级进入每一层目录/、var、www、html。任何一层目录缺了x权限路径就断在那里。文件本身的权限再完美也没用因为你压根到不了文件面前。这解释了很多诡异现象明明/var/www/html/index.html是644属主也正确但浏览器或脚本就是打不开。此时要检查每一层目录的权限尤其是html的上级目录是否被误设成了700。Linux 提供了namei命令一条命令列出路径所有组件的权限namei -l /var/www/html/index.html输出会逐行显示每一级路径的属主、属组和权限一眼就能定位是哪层目录拦住了。6.4 权限排查的常用命令组合最后把这几年用得最顺的排查命令组合列出来当速查表用ls -l 文件名 # 快速看权限、属主属组、大小 stat 文件名 # 看详细时间戳、权限、特殊位 id [用户名] # 看当前用户和组成员 getfacl 文件名 # 如果有 ACL看扩展权限 namei -l 路径 # 看路径各级目录权限 find / -perm -4000 # 找 SUID 文件关于 ACL简单提一句如果ls -l权限位后面多了一个比如-rw-r--r--说明文件有扩展访问控制列表ACL用getfacl查看。ACL 可以在基础 rwx 之上对单个用户做精细授权常见于复杂协作场景。普通环境里先掌握好 chown/chmod 这一套基础再按需了解 ACL 就够用了。说实话这些内容单独看每一条都不难难的是把它们串在一起形成肌肉记忆。我刚学的时候也背过权限表但真正记住还是在解决了几次线上权限问题之后。你现在可以把这篇当作一篇地图遇到问题回来对着查等哪一天你不再想这个选项什么意思而是条件反射地知道该用ls -l还是stat、该chown还是chmod那就真的入门了。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑