ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

Linux文件权限与chmod详解:从777到755,彻底搞懂权限管理

Linux文件权限与chmod详解:从777到755,彻底搞懂权限管理 看到好多新手在Linux上折腾文件权限动不动就chmod 777一把梭今天必须把这个命令彻底讲透。如果你刚接触 Linux或者之前只知道复制粘贴网上的权限命令这篇内容值得你从头看一遍。我会从权限的数字规律讲到实际排错包括chmod 777到底是什么意思、什么时候用、什么时候千万别用以及为什么你执行了chmod却还是报“Permission denied”。全程用大白话不整虚的。1. 做权限操作之前先看懂Linux文件那10个字符在终端里敲ls -l你会看到类似下面这一行输出-rw-r--r-- 1 root root 1024 Jan 1 00:00 example.txt这一行最左边的-rw-r--r--不是乱码它把文件的类型和权限全写出来了。去掉表示文件类型的-后面其实是三组字符rw-、r--、r--分别对应文件所有者u、文件所属组g、其他用户o。每组三个位置代表三种基本权限rread读取文件内容、列出目录里的文件名。wwrite修改文件内容、在目录里新建/删除/重命名文件。xexecute执行文件对目录来说是能否进入目录并访问里面的文件常说的“x权限决定你能不能cd进去”。所以-rw-r--r--的意思是所有者能读和写所属组只能读其他人也只能读。如果某个位置是-就代表没有这个权限。例如-rw-r--r--中所有者那组没有x说明这个文件不能被执行。1.1 目录的x权限是很多人理解错的坎文件权限和目录权限的r、w、x虽然有相似名字但实际效果完全不同。对目录来说r只代表你能列出目录里“有哪些文件名”但不能获取文件的任何属性信息。x才代表你能“穿过”这个目录访问里面文件的实际 inode 信息。没有x权限即使有r权限ls -l也会报错或者看不到完整信息。w只能在有x的情况下才有意义否则你连进入目录的方式都没有谈何创建文件。常见误区是给目录只设置r和w结果发现进不去目录报Permission denied。解决办法就是补上x最常用的就是chmod 755 目录名这也是大多数系统目录的标准权限。1.2 那个让你蒙圈的“数字权限”是怎么算出来的chmod 777里的777每个数字是权限的二进制编码。单组权限里r对应 4w对应 2x对应 1没有权限就是 0。把需要的值加在一起就得到一个 0~7 的数字7 421rwx6 42rw-5 41r-x4 4r--0---于是chmod 777 所有者(7)、所属组(7)、其他人(7) 都有rwx权限。实际工作中644是最常见的文件权限所有者可读写其他人只能读。755是最常见的目录/可执行文件权限所有者可读写执行其他人可读可执行但不可写。1.3 还有个四位数字开头的“特殊权限”有时你会看到chmod 1777或chmod 4755这里的第一位叫特殊权限位常见有三种setuid4文件执行时进程提权为文件所有者的身份运行典型代表是/usr/bin/passwd。setgid2目录设置了它新建文件的所属组会继承父目录的组文件设置了它执行时以文件所属组的身份运行。sticky bit1目录设置了它只有文件所有者、目录所有者或 root 才能删除/重命名目录里的文件典型代表是/tmp。对大多数日常操作你基本用不到特殊权限但看到别人用必须认得。比如chmod 1777 /tmp的目录尾部权限是rwxrwxrwt最后一位t就是 sticky bit 的标志。2. chmod 777的适用场景和必须警惕的副作用chmod 777大概是互联网上被滥用最严重的 Linux 命令之一。它不是不能用但用之前得知道代价是什么。2.1 什么时候确实需要777说句公道话个别场景下 777 是最省事的方案。比如你在本机用一个纯测试环境目录里要临时跑一些生成缓存文件的脚本而且脚本运行用户不确定再比如你在容器里调试挂载卷主机和容器 UID 不一致临时放开权限最快。还有像某些 Android 用户大量拷贝文件、或者在一台完全隔离的虚拟机上刷机调试也会选择 777。另一个高频场景是不熟悉 UID 映射的 Docker 挂载目录。容器里的进程可能以 UID 1000 跑宿主机用户是 UID 1000两边一碰撞挂载目录经常出现Permission denied。图省事的时候大家会对挂载目录执行chmod 777。2.2 为什么大家都劝你别随便777主要原因是安全问题。权限设计的初衷就是最小化暴露面777 等于对系统上所有用户开放全部读写执行权限。在共享服务器上别人可以随意修改你的脚本、删除你的文件、往目录里塞入木马如果 777 的是 Web 站点目录配合一个上传漏洞整个站点基本拱手让人。还有一个很多人没意识到的问题777 会把文件的所有权语义破坏掉。你chmod 777之后别人虽然改不了文件所属者但可以把它删掉再建一个同名文件新文件就归别人了。这在审计时很麻烦。2.3 比777更合理的替代方案遇到权限不够先不要急着 777按照下面的优先级思考把用户加入对应组目录属于www-data组那就把当前用户usermod -aG www-data 你的用户名然后给目录设chmod 750或chmod 2775。组内成员协作组外无权限。使用 ACL 精细授权用setfacl -m u:某用户:rwx /目录可以只给某个具体用户开权限不改变文件原始属组。调整属主属组确认这个目录本来就是你的那就chown 你的用户:你的组 /目录而不是让其他人都来分一杯羹。改挂载参数如果是 Docker 挂载卷或 NFS 盘优先检查挂载参数里有没有uid、gid之类的选项这比改 777 更根本。只有当上面的方案全部走不通或者在你的单机隔离测试环境下真的无所谓再考虑 777。3. 数字模式与符号模式chmod的两种中文习惯表达chmod支持两种参数写法一种是我们上面说的数字模式另一种是符号模式。很多老手常混着用但新手最好两个都掌握因为看别人的脚本时两种都能碰到。3.1 数字模式的几个实用细节数字模式本质是“一次设置最终完整权限”不是增量式修改。你写chmod 644 file那么文件最终权限就是rw-r--r--之前有什么权限都会被覆盖。所以数字模式适合你知道自己想要什么最终结果的情况。三位数字不够用时还可以写四位例如chmod 4755 script。但注意如果你写chmod 755特殊权限位会被重置归零。改过 setuid 的程序再跑一次普通chmod 755setuid 位就掉了这是排查“为什么程序突然不以 root 运行了”的关键。3.2 符号模式增量修改用起来更顺手符号模式的语法是chmod [ugoa][-][rwx] 文件u所有者g所属组o其他用户a全部相当于ugo常用写法chmod x script.sh给所有用户增加执行权限等价于chmod ax script.shchmod uw file只给所有者添加写权限chmod go-w file移除组和其他用户的写权限chmod urwx,gorx file显式指定每个角色的权限我去到线上环境快速调整时只要不是需要整体重设我更习惯用符号模式因为不会误清掉特定位。比如想给一个脚本加执行权限chmod x run.sh不会影响它的读写权限比chmod 755 run.sh来得更温和。3.3 递归修改小心把不该改的一起改了chmod -R 755 /某个目录会递归修改目录下所有文件和子目录的权限。这句话看起来简单实际执行时要极其谨慎它会同时把普通文件的权限也改成 755这会让所有文件都可执行既不安全也没必要。如果你只想改目录的权限可以用find /某个目录 -type d -exec chmod 755 {} \; find /某个目录 -type f -exec chmod 644 {} \;这样目录是750文件是640可执行脚本单独处理。虽然命令长一点但效果专业得多。更只要的坑是别轻易对系统目录执行chmod -R。比如有人想“修复”权限直接chmod -R 777 /usr很可能把整个系统搞到半瘫。日常操作时我会先在目标目录里find出来看看数量确认范围再动手。4. 执行了chmod却没用常见失败场景逐个排如果哪天你执行chmod 777还是不生效报Operation not permitted或者Permission denied不一定是命令写错很可能是下面几种情况。4.1 文件系统挂载参数和只读盘最常见的原因之一是挂载参数里带了ro也就是只读挂载。你可以用mount | grep 你的目录看到ro字样那就得重新挂载或用mount -o remount,rw 挂载点来改单靠 chmod 改不了。还有的企业 NAS、NFS 挂载盘服务端可能限制了权限位即使你在客户端chmod 777也只是本地缓存服务端仍按默认权限处理。这经常发生在 PV 存储和网络盘上排查时看一眼 mount 参数问题通常一目了然。4.2 root用户、sudo与文件系统扩展属性root 用户理论上可以改任何文件权限但如果报Operation not permitted那大概率是文件系统启用了只读属性或扩展安全属性。你可以用下面命令查lsattr 文件路径如果看到iimmutable属性就说明文件被锁定了需要先去除再改chattr -i 文件路径还有一种情况是你在 Android 的/storage/emulated/0/android/data/...这类路径下执行 chmod。这个路径在 Android 上挂载的是 FUSE 文件系统底层对mode有限制很多情况下根本不支持 chmod只有在/data内部目录才可以。今年很多人在手机模拟器或容器里遇到unable to chmod基本都是这个原因——不是命令语法问题是文件系统不支持。4.3 用户和组搞错了权限给错人你把自己chmod 777了却用另一个普通用户访问当然会失败。chmod 777已经让所有用户都有权限了还访问失败那就不是权限位的问题而是文件系统上层有别的限制。确认当前用户身份用id查看文件所有者用ls -l或stat。我在排查权限问题时第一反应是stat -c %a %U %G 文件路径看到数字权限、用户、组一目了然比ls -l更直观。4.4 umask把新建文件的权限“扣掉”了umask是 shell 里的一个掩码决定新建文件默认权限。比如umask 022时新建文件默认权限是666 - 022 644新建目录是777 - 022 755。有时你创建一个脚本系统默认没给执行权限于是想用chmod x script.sh这是正常的。但如果你希望以后所有新建脚本默认带执行权限可以临时设置umask 022注意这只是减法逻辑不代表 666 就绝对会出现。从安全角度不建议把用户默认 umask 改成 000否则新建的文件全变成 666等于裸奔。建议用umask 027这样组内可读其他用户无权限。5. 实际使用中的命令组合和运维速查聊了这么多理论最后直接给一份我日常高频使用的 chmod 操作清单按场景分类。5.1 常用权限设置速查表需求命令文件默认权限chmod 644 file脚本可执行chmod x script.sh或chmod 755 script.sh目录权限chmod 755 dirWeb 站点目录chmod 644文件 chmod 755目录组内协作目录chmod 2775 dirsetgid 组读写执行完全放权仅限隔离环境chmod 777 file_or_dir递归改目录不动文件find dir -type d -exec chmod 755 {} \;递归改文件不动目录find dir -type f -exec chmod 644 {} \;查看当前 umaskumask查看文件详细权限stat -c %a %U %G file5.2 在银河麒麟这类国产系统上执行chmod这几年国产化办公环境越来越常见银河麒麟、统信UOS等系统因为要兼容多种使用习惯桌面环境有时会把普通用户变成 sudo 组或者在挂载 Windows 分区时默认给所有文件一个比较宽的权限。在麒麟系统上若遇到 U 盘或移动硬盘里的文件无法执行先看挂载点是否用ntfs-3g或vfat挂载。FAT32 和 NTFS 本身不记录 Linux 权限chmod只是临时模拟重插后可能就会丢失真正的办法是改/etc/fstab的挂载参数例如/dev/sdb1 /mnt/data ntfs-3g defaults,uid1000,gid1000,umask022 0 0这样挂出来后用户自动有权限不需要每次 chmod。如果你的系统装的是银河麒麟用sudo chmod 777可能因为只读挂载不生效优先检查mount输出。5.3 备份脚本和定时任务的权限心得个人经验写 shell 脚本时我一般给脚本750权限属主和属组可执行其他用户不可读不可执行。这样即使脚本里有数据库密码、密钥路径之类的敏感变量也不容易被随便窃取。另一个习惯是定时任务cron里的脚本能放到/usr/local/bin权限统一755日志和输出文件则让脚本自己用umask 077控制避免每次创建文件都被其他用户读到。5.4 解压文件出现权限混乱的连带故事热搜词里那个“linux 解压文件乱码”其实也常和权限挂钩。某些 zip 包在 Windows 上压缩时带了奇怪的属主信息解压出来权限变成rwx------导致程序访问不了。处理办法很简单unzip file.zip chmod -R urwX,gorX,go-w 解压目录注意这里用了大写X它表示“只给目录和已经有执行权限的文件加执行权限”。这个特性比chmod -R x安全得多不会把普通文本文件全变成可执行文件。这是 chmod 一个很容易被忽略但极其好用的细节。5.5 别忘了用chmod修改符号链接的误区最后提一个高频误区对符号链接直接chmod通常不起作用甚至报错。Linux 下符号链接的权限固定是lrwxrwxrwx真正生效的是它指向的目标文件。如果你需要修改链接目标的权限直接操作目标路径想改链接本身的所有关系用chown -h参数。很多人刚学 chmod 时会对软链接执行chmod 777发现无反应这不是 bug而是设计如此。6. 我踩过一次印象深刻的chmod坑递归权限把应用搞崩最后一次分享一个真实事故。有次我给一个多模块 Java 应用的日志目录清理权限没细看就直接chmod -R 777 /opt/app。当时以为只是放开了日志目录结果整个应用目录下所有 jar 包、配置文件、密钥文件全变成了 777。测试环境倒没炸但等应用重启时因为 jar 包权限变化应用启动脚本和第三方组件的行为出现了一些很隐蔽的异常用户会话数据也能被其他系统账号读到。那次之后我给自己定了规矩任何递归操作之前先find看数量和类型再执行chmod -R对敏感目录宁可用find -type d和-type f分开改。回到开头那个问题chmod 777能不能用能但要有条件地用。它像一个万能钥匙能开所有锁但也意味着谁捡到都能开。真正稳定、可维护的服务器环境都是从最小权限一步步组装的。遇到权限报错先从挂载方式、用户归属、umask、文件属性四个方向排查实在没招了再 777这才是工程化思维。
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进