文件系统

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 位允许可执行文件以文件所有者的权限运行,而不是以启动它的用户权限运行。例如,如果一个可执行文件设置了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 位对文件和目录都有影响

设置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位用于目录时,该目录中的所有文件只能由其所有者修改。

使用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
# 或者所有者拥有所有权限,组拥有写入权限,其他人拥有执行权限

setuidsetgidsticky位分别用值421表示,例如:

# 在目录上设置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编号。修改xa都会更改同一个文件。

符号链接

符号链接是从一个位置到另一个位置的链接。符号链接是一个新文件,与原始文件分开,链接到原始文件。

使用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中

  • 多个文件系统可以被挂载并抽象为一个逻辑树

参考资料

最后更新于