文件系统
Linux 文件系统
这意味着打印机、扫描仪、终端屏幕、任何进程的代码——这些都是文件。你在文件系统上的文件是一串字节连接在一起创建的有意义的内容。
目录也是文件,它们简单地包含当前目录中存在的文件和目录列表,就像一棵树。这样做的美妙之处在于你可以"打开"一个目录文件来查看其内容:
$ vim .
" ====================================================================
" Netrw Directory Listing (netrw v168)
" /Users/user/folder
" Sorted by name
" Quick Help: <F1>:help -:go up dir D:delete R:rename s:sort-by
" x:special
" ===================================================================
../
./
another_folder/
some_file.txt
some_folder/
这就是UNIX存储当前目录的方式。它包含当前目录中的文件和目录列表。
inode(索引节点)
要拥有文件系统,你需要一个结构来管理它。文件系统不仅包含数据,还包含关于这些数据的一些信息,称为元数据
(metadata)。这包括数据存储在哪里、谁拥有它以及谁可以看到它。这就是inode
的作用——一个用于文件元数据的数据结构。
$ ls -li
total 0
287009 drwxr-xr-x 9 user staff 288 23 Oct 07:36 another_folder
286999 -rw-r--r-- 1 user staff 110 9 Oct 11:37 some_file.txt
287002 drwxr-xr-x 5 user staff 256 23 Sep 11:46 some_folder
每个文件都有一个唯一的inode编号
(上面第一列)是文件存在时的唯一标识符。
stat 命令
你可以使用stat
命令来查看这个元数据:
$ stat -LF some_folder
drwxr-xr-x 8 user staff 256 Feb 05 13:37:00 2021 some_folder
drwxr-xr-x
是文件权限8
是硬链接计数user staff
是用户和组名;文件和目录的所有权基于创建它们的用户的默认 uid(用户ID)和 gid(组ID)256
是文件大小,即文件中的字节数Feb 05 13:37:00 2021
是最后修改日期
文件权限
每个文件都有相关的权限,总共12个权限位:

setuid 位(设置用户ID位)
setuid
位允许可执行文件以文件所有者的权限运行,而不是以启动它的用户权限运行。例如,如果一个可执行文件设置了setuid
位并且由root拥有,那么当以普通用户身份启动时,它将以root权限运行。
一个设置了setuid
权限的可执行文件示例是passwd
,你可以使用它来更改登录密码。你可以使用ls
命令来验证:
$ ls -l /usr/bin/passwd
-rwsr-xr-x 1 root root 54256 Mar 26 2019 /usr/bin/passwd
你可以通过在"user"部分的执行位x
位置看到s
来识别setuid
位的存在(见上面的命令输出)。
s
意味着执行位已设置,否则你会看到大写的S
。这发生在setuid
位已设置但执行位未设置时,向用户显示不一致:如果执行位未设置,setuid
位无效。
setgid 位(设置组ID位)
设置setgid
位的文件以拥有该文件的组的权限执行。换句话说,进程组ID将与文件相同。
当setgid
用于目录时,在该目录中创建的文件将由父目录组拥有,而不是由创建它们的用户拥有。这通常用于简化文件共享(文件可以被属于特定组的所有用户修改)。
$ ls -l some_folder
drwxrwsr-x 1 user staff 256 Feb 6 04:37 some_folder
你可以通过在"group"部分的执行位x
位置看到s
来识别setgid
位的存在(见上面的命令输出)。
s
意味着执行位已设置,否则你会看到大写的S
。这发生在setgid
位已设置但执行位未设置时,向用户显示不一致:如果执行位未设置,setgid
位无效。
sticky 位(粘滞位)
当sticky
位用于目录时,该目录中的所有文件只能由其所有者修改。
使用sticky
位的典型情况涉及/tmp
目录。通常它对系统上的所有用户都可写,因此为了防止一个用户删除另一个用户的文件,设置了sticky位:
它通常对系统上的所有用户都可写,因此设置sticky
位以防止一个用户修改或删除另一个用户的文件:
$ ls -ld /tmp
drwxrwxrwt 2 root wheel 64 Feb 7 08:50 /tmp
你可以通过在"other"部分的执行位x
位置看到t
来识别sticky
位的存在(见上面的命令输出)。
t
意味着执行位已设置,否则你会看到大写的T
。这发生在sticky
位已设置但执行位未设置时,向用户显示不一致:如果执行位未设置,sticky
位无效。
rwx 权限
对于文件:
r
可以读取(read)w
可以写入(write)x
可以执行(execute)
对于目录大致是:
r
可以列出文件w
可以创建文件x
可以cd
进入和修改文件
条目类型
然而,如果你查看元数据:
$ stat -LF
crw--w---- 1 user tty 16,2 Feb 7 09:29:10 2021 (stdin)
你会发现权限字符串crw--w----
包含10个字符。第一个是特殊的条目类型字符,描述文件类型:
b
- 块特殊文件(block special file)c
- 字符特殊文件(character special file)d
- 目录(directory)l
- 符号链接(symbolic link)s
- 套接字链接(socket link)p
- FIFO(命名管道)-
- 普通文件(regular file)
chmod 命令
你可以使用chmod
工具来更改文件权限。在后端,chmod
与文件的inode交互。
由于你需要3位来表示每个权限,你可以将其转换为整数并传递给chmod
,例如:
$ chmod 721 .
# 或者 rwx-w---x
# 或者所有者拥有所有权限,组拥有写入权限,其他人拥有执行权限
setuid
、setgid
和sticky
位分别用值4
、2
和1
表示,例如:
# 在目录上设置setgid位
$ chmod 2775 .
更多使用示例参见此处
你也可以限制自己的访问,移除自己的所有读取、写入和执行权限。如果文件元数据存储在文件本身中,你将无法再次更改权限(因为你无法写入文件)。这就是inode很酷的另一个原因:它们总是可以被文件所有者和root修改,所以你可以恢复你的权限。
文件链接
硬链接(Hard links)和符号链接(Symbolic links)是链接到硬盘驱动器上文件的两种不同方法。这些方法是文件系统的一部分,定义了文件及其位置。

硬链接
硬链接
是指向同一文件的两个文件名(你可以将它们视为文件别名)。例如,.
和..
是系统上当前目录和父目录的硬链接。
使用ln
创建硬链接:
$ ls -li
total 0
1637699 -rw-r--r-- 1 user wheel 0 Feb 7 10:03 a
# 创建x作为a的硬链接
$ ln a x
$ ls -li
total 0
1637699 -rw-r--r-- 2 user wheel 0 Feb 7 10:03 a
1637699 -rw-r--r-- 2 user wheel 0 Feb 7 10:03 x
注意两个文件具有相同的inode编号。修改x
或a
都会更改同一个文件。
符号链接
符号链接
是从一个位置到另一个位置的链接。符号链接是一个新文件,与原始文件分开,链接到原始文件。
使用ln
创建符号链接:
$ ls -li
total 0
1637699 -rw-r--r-- 1 user wheel 0 Feb 7 10:03 a
# 创建y作为a的符号链接
$ ln -s a y
$ ls -li
total 0
1637699 -rw-r--r-- 2 user wheel 0 Feb 7 10:03 a
1638321 lrwxr-xr-x 1 user wheel 1 Feb 7 10:09 y -> a
y
是一个符号链接,是一个新的小文件(见大小为1)。修改y
会更改a
。
文件结构
文件系统可以被视为树状数据结构。每个节点(inode)都有指向其父节点、自身和所有子节点的指针。这形成了目录结构。

总结
文件系统使用inode构建
inode在文件系统上是唯一的
用户是文件属性的一部分;此信息存储在inode中
多个文件系统可以被挂载并抽象为一个逻辑树
参考资料
How Unix Works: Become a Better Software Engineer - 深入了解UNIX工作原理
Julia's Drawings: Unix permissions - UNIX权限的可视化解释
最后更新于