第 5 章 · 01 解读 :权限位与文件类型 本节摘要:几乎所有 Linux 教程都会让你敲 ,却很少有人讲清「为什么是 7、5、5」「为什么权限写成 这种怪模样」。答案全在 输出最左边那十位字符里。本节要把这十位彻底拆开:第一位是文件类型( 普通、 目录、 链接、 / 设备),后九位是三组权限(属主 / 属组 / 其他 ,各 )。理解了这十位,你就拿到了 Linux 权限系统的「身份证」——后续 的八进制换算、 的身份判定、 的默认权限计算,全都建立在它之上。这是本章的起点,也是全章最该吃透的一节。 内容来源:原项目「Linux 命令大全」 与 ,精选并套用体系化模板。 学习目标 阅读完本节,你应当能够: 一眼读出 最左列十位字符的含义,说出第 1 位文件类型与后 9 位权限各是什么。
ls -l:权限位与文件类型本节摘要:几乎所有 Linux 教程都会让你敲
chmod 755,却很少有人讲清「为什么是 7、5、5」「为什么权限写成rwxr-xr-x这种怪模样」。答案全在ls -l输出最左边那十位字符里。本节要把这十位彻底拆开:第一位是文件类型(-普通、d目录、l链接、c/b设备),后九位是三组权限(属主u/ 属组g/ 其他o,各rwx)。理解了这十位,你就拿到了 Linux 权限系统的「身份证」——后续chmod的八进制换算、chown的身份判定、umask的默认权限计算,全都建立在它之上。这是本章的起点,也是全章最该吃透的一节。
内容来源:原项目「Linux 命令大全」
command/ls.md与command/chmod.md,精选并套用体系化模板。
阅读完本节,你应当能够:
ls -l 最左列十位字符的含义,说出第 1 位文件类型与后 9 位权限各是什么。-(普通文件)、d(目录)、l(符号链接)、c(字符设备)、b(块设备)。u、属组 g、其他 o,各拥有 r/w/x。rwxr-xr-x 这种字符串与 755 八进制互 相换算,解释每一组三位二进制怎么对应一位八进制。ls -l 整行其余列(硬链接数、属主、属组、大小、时间、文件名)与最左列的关系。ls -l 那十位字符到底在表达什么敲一行 ls -l,你会看到这样的输出:
$ ls -l total 8 -rw-r--r-- 1 user staff 651 Aug 4 12:53 README.md drwxr-xr-x 3 user staff 4096 Aug 4 12:55 src lrwxrwxrwx 1 user staff 3 Aug 4 12:56 link -> src
最左边那一列(-rw-r--r--、drwxr-xr-x、lrwxrwxrwx)就是「文件模式」(file mode),它由 10 位字符 组成,前 1 位是文件类型,后 9 位是三组权限。把这一列读明白,你就掌握了 Linux 文件系统里最重要的元数据。
第 1 位只有一个字符,标识「这个东西是什么」。最常见的是五种:
| 字符 | 类型 | 说明 |
|---|---|---|
- |
普通文件 | 文本、二进制、图片、压缩包……绝大多数文件都是它 |
d |
目录 | directory,目录本身在 Linux 里也是一种特殊文件 |
l |
符号链接 | symlink,类似 Windows 的快捷方式,指向另一个文件 |
c |
字符设备 | 按字符流读写的设备,如 /dev/tty、/dev/null |
b |
块设备 | 按块读写的设备,如 /dev/sda(硬盘)、/dev/ram |
💡 技巧:还有几种较少见的,如
s(套接字 socket)、p(命名管道 FIFO),日常几乎用不到,见到s/p多半是/var/run/下进程通信用的特殊文件。先记住前五种,你已经能解读 99% 的ls -l输出。
注意:- 和 d 是你日常打交道的绝对主力。判断一个路径是文件还是目录,看第 1 位就够,不必 stat。
c 与 b 的区别字符设备(c)和块设备(b)是 Unix 设备抽象的两类。它们的差别不在「是什么设备」,而在「怎么访问」:
$ ls -l /dev/null /dev/tty /dev/sda /dev/ram0 crw-rw-rw- ... /dev/null # c: 字符设备, 一次一个字符 crw-rw-rw- ... /dev/tty # c: 终端, 按键一个个读 brw-rw---- ... /dev/sda # b: 块设备, 整块整块读写, 可寻址 brw-rw---- ... /dev/ram0 # b: 内存盘
/dev/null(黑洞)、/dev/random(随机数)都是。设备文件本身不存数据,它只是「访问设备驱动的入口」——读 /dev/sda 实际是调用硬盘驱动。这是 Linux「一切皆文件」的延伸:连硬件都被抽象成文件。日常你几乎不直接操作设备文件(挂载后才用),但看到 c/b 就该意识到:这不是普通文件,是设备入口。
后 9 位被等分成 三组,每组 3 位,从左到右依次表示「属主」「属组」「其他」三类人对该文件的权限。
- rwx r-x r-x ↑ ↑ ↑ ↑ 类型 属主 属组 其他 u g o
u):文件的主人,即创建它的用户(或被 chown 改到的用户)。g):文件所属的用户组,通常是主人所在的主组。o):既不是属主、也不在属组里的「其他所有人」。每组里的三位是固定的 r/w/x,如果不具备该权限,对应位置就是 -:
| 位 | 普通文件含义 | 目录含义(下一节深讲) |
|---|---|---|
r |
能读内容(cat/less) |
能列出目录里的文件名(ls) |
w |
能改内容(vim/echo >) |
能增删目录里的文件 |
x |
能执行(脚本/二进制) | 能进入该目录(cd)与访问 inode |
关键概念:「三类人 × 三种权限」的 9 位模型是整个 Linux 权限系统的最小骨架。
rwx三位对「文件」和「目录」含义不同,这是本章第 03 节要专讲的难点;本节先把 9 位的结构和读法吃透。
看到一个 ls -l 行,训练自己按「类型 → 主 → 组 → 其他」的四段式默读:
-rw-r--r-- 读作: 普通文件, 属主 rw, 属组 r, 其他 r drwxr-xr-x 读作: 目录, 属主 rwx, 属组 r-x, 其他 r-x lrwxrwxrwx 读作: 链接, 属主 rwx, 属组 rwx, 其他 rwx
💡 技巧:符号链接(
l)总是显示rwxrwxrwx,这是因为符号链接的权限由它指向的目标文件决定,链接本身权限位是「假」的——你chmod一个符号链接,改的其实是目标文件(详见第 02 节踩坑)。
ls -ld /var/log # -d 让 ls 显示目录本身而不是它里面的内容 # drwxr-xr-x root root ...
第 1 位是 d,后 9 位里「其他」那一组(r-x)有 x,说明任何用户都能 cd 进去。如果是 drwxr----,其他用户那组没有 x,你就进不去,即使能 ls 出文件名也打不开。
ls -l /tmp/* | grep '^........w.' # 第 10 位(其他 w)是 w 的行 # 或更直观的写法: 其他组有 w ls -l /etc/* | grep 'rw.r.w.' # 简化模式匹配, 不严谨但够用
「其他 w」(o 有 w)是安全审计要重点关注的——它意味着任何人都能改这个文件。/etc/passwd、/etc/shadow、~/.ssh/authorized_keys 绝不该出现其他 w。
stat 看更精确的权限信息ls -l 给的是「字符表示」,stat 给的是「八进制表示」,两者互补:
$ stat -c '%a %A %n' README.md 644 -rw-r--r-- README.md
%a 是八进制权限(644),%A 是字符权限(-rw-r--r--),%n 是文件名。当你想确认八进制到底是多少,stat -c '%a' 比自己换算更省事——但本节后面还是要教你自己换算,因为这是理解权限的关键。
ls -l把 ls -l 的每一列对一遍:
-rw-r--r-- 1 user staff 651 Aug 4 12:53 README.md └───┬───┘ └┘ └─┬─┘ └─┬─┘ └┘ └─────┬─────┘ └───┬───┘ 权限 链接数 属主 属组 大小 修改时间 文件名
. 和上级目录指向它)。u/g/o 里你属于哪一类——这是第 04 节 chown 的主题。💡 技巧:看到「链接数」特别大的目录(比如
5以上),多半是子目录多——每加一个子目录,父目录的链接数 +1(因为子目录的..指向父目录)。这是第 2 章 inode 的延伸知识。
ls -la 看隐藏文件的权限ls -l 默认不显示以 . 开头的隐藏文件。要查看隐藏文件(包括关键的 .bashrc、.ssh/),加 -a:
$ ls -la ~/ total 120 drwxr-xr-x user staff ... . drwxrwxr-x root admin ... .. -rw------- user staff ... .bash_history -rw-r--r-- user staff ... .bashrc drwx------ user staff ... .ssh ← 注意: 700, 私人
注意几个关键隐藏文件的权限惯例:
~/.ssh/ 必须是 700(rwx------),SSH 客户端会检查,权限过宽会拒绝使用私钥。~/.bash_history 通常是 600(只有自己能读,里面有命令历史可能含敏感信息)。.(当前目录)和 ..(上级目录)也列出,从中能看到父目录权限。ls -li 看 inode 编号-i 显示 inode 编号,把第 2 章(inode 模型)和本章(权限模型)串起来:
$ ls -li file hardlink 12345 -rw-r--r-- user 651 ... file 12345 -rw-r--r-- user 651 ... hardlink
两个文件 inode 编号相同(都是 12345),说明 hardlink 是 file 的硬链接——它们共享同一份 inode 数据,权限自然也完全一样(因为权限存在 inode 上,不是文件名上)。这就是为什么硬链接改权限会互相影响——它们本质是同一个文件。
关键概念:权限位存在 inode 里,不在文件名上。硬链接共享 inode,所以共享权限;符号链接有自己的 inode(但权限位是假的,跟随目标)。这是把第 2 章 inode 知识和本章权限知识打通的关键。
x 也能用最常见的误会:看到 drwxr--r-- 的目录,以为「其他有 r,我能列目录」。其实你 能 ls 出文件名,但 cd 不进去,也打不开里面的文件。因为目录的 x 是「进入权限」,没有它你访问不到目录里文件的 inode。
$ ls -ld shared/ drwxr----- user staff ... # 你属于 others, 只有 r-- 没有 x $ ls shared/ # 能列出文件名(有 r) a.txt b.txt $ cat shared/a.txt # 但打不开(没 x, 访问不到 inode) cat: shared/a.txt: Permission denied
这种「能 ls 却打不开」的现象,根因就是目录缺 x。详解见第 03 节。
rwxrwxrwx ≠ 八进制 777 是「巧合」很多新手把 rwxrwxrwx 记成「777」,但说不清为什么。换算规则是:每一组 3 位 rwx 看成 3 位二进制,有权限的位置是 1,无权限是 0,这 3 位二进制转成 1 位八进制。
rwx = 111 = 7 rw- = 110 = 6 r-x = 101 = 5 r-- = 100 = 4 -wx = 011 = 3 -w- = 010 = 2 --x = 001 = 1 --- = 000 = 0
所以 rwxr-xr-x = 7 5 5 = 755;rw-r--r-- = 6 4 4 = 644。你只需要记住「r=4、w=2、x=1,相加得每组八进制」:
rwx = 4+2+1 = 7r-x = 4+0+1 = 5rw- = 4+2+0 = 6关键概念:为什么用八进制而不是十进制? 因为 3 位二进制正好对应 1 位八进制(
000111对应07),一组权限用一个八进制字符就能精确表达。这是 Unix 早期设计者留下的优雅——八进制与 3 位权限分组天然契合。
$ ls -l link lrwxrwxrwx user staff 3 ... link -> src
看到 lrwxrwxrwx 别慌——符号链接的权限位是「占位」,永远是 rwxrwxrwx。真正生效的是它指向的目标文件的权限。你 chmod 700 link,改的是 src 的权限,不是 link 自己的(大多数系统上 chmod 会跟随链接)。
ls -l 的输出按空格切,权限位解析错写脚本解析 ls -l 时,新手常 split(' '),结果遇到文件名带空格、属主名特别长等情况就崩。正确做法是用 stat 或 find -printf,不要解析 ls 的输出——这是 POSIX 文档明确警告的(参见第 3 章 awk 节关于结构化解析的讨论)。
# 不要这样(脆弱): ls -l | awk '{print $1}' # 改用 stat(稳健): stat -c '%A' *
ls -l 第 1 位告诉你「这个东西在文件系统层面是什么类型」,但不告诉你「内容是什么」。比如:
-rw-r--r-- image.jpg # 第 1 位是 -, 是普通文件 -rw-r--r-- report.pdf # 第 1 位是 -, 也是普通文件 -rwxr-xr-x script.sh # 第 1 位是 -, 还是普通文件(有执行位而已)
image.jpg、report.pdf、script.sh 在 ls -l 看来都是普通文件(-),文件类型位区分不出「图片 vs 文档 vs 脚本」。Linux 不靠扩展名(那是 Windows 的习惯),而是靠文件内容头的 magic number 判断实际格式——file 命令干的就是这事:
$ file image.jpg report.pdf script.sh image.jpg: JPEG image data, ... report.pdf: PDF document, ... script.sh: Bourne-Again shell script, ASCII text executable
⚠️ 注意:别用
ls -l判断文件内容格式,它只给文件系统层面的类型。想知道「这是什么内容」,用file命令。这一点对从 Windows 转过来的新手尤其重要——Windows 靠扩展名,Linux 靠 magic number。
ls -l 最左列是 10 位「文件模式」:第 1 位是文件类型(-/d/l/c/b),后 9 位是三组权限。- 普通、d 目录、l 链接、c 字符设备、b 块设备——判断文件/目录看第 1 位。u、属组 g、其他 o,各 r/w/x,缺权限位是 -。r 是读/列目录,w 是改/增删文件,x 是执行/进入目录——第 03 节专讲。rwx = 111 = 7,r-x = 101 = 5,记住 r=4、w=2、x=1 相加即可换算所有组合。rwxrwxrwx,生效的是目标文件权限。ls -l 输出别用 awk 按空格切,改用 stat -c '%A %a %n',稳健得多。下一节进入「改权限」:chmod。它有两套写法——符号式(u+x、g-w)和八进制(755)。符号式直观、适合增量调整;八进制精确、适合整体覆盖。学完这两套写法,你就能在任何场景下精准地把权限调到想要的样子。