Linux 文件系统知识
😊
A simple description of the UNIX system, also applicable to Linux, is this: “On a UNIX system, everything is a file; if something is not a file, it is a process.“ Linux 下一切皆文件。
1 文件系统(File system)
file system
或 filesystem
(文件系统,通常简称为 fs
),控制着数据的存储和检索方式。
如果没有文件系统,放置在存储介质中的数据将是一大批数据,无法判断一段数据从哪里开始,或者在哪里停止。通过将数据分成几块并给每块一个名称,数据很容易被隔离和识别。它的名字来源于基于纸张的数据管理系统的命名方式,每组数据被称为文件。用于管理数据组及其名称的结构和逻辑规则称为文件系统。
文件系统是根据它们的用途来进行定义的。有许多不同种类的文件系统。每一种都有不同的结构和逻辑、速度、灵活性、安全性、大小等属性。有为操作系统、网络、数据库和其他专用文件系统定义了的文件系统。在操作系统中,文件系统可以定义为硬盘、闪存、RAM 或光盘。
本文讨论 Linux 系统上基于硬盘的文件系统。
1.1 文件系统架构
文件系统主要由3层组成。从上到下:
- 逻辑文件系统(Logical file system):在 API 的帮助下与用户应用程序交互,以提供打开、读取、关闭等操作,并将请求传递给下面的层。
- 虚拟文件系统(Virtual file system):允许物理文件系统的多个实例同时运行。
- 物理文件系统(Physical file system):处理磁盘的物理方面,同时管理和存储正在读取和写入的物理内存块。
文件系统应该具备以下特征:
- 空间管理(Space Management:):数据在存储设备上的存储方式。与其中应用的内存块和碎片化管理。
- 文件名(Filename):文件系统可能对文件名有某些限制,例如名称长度、特殊字符的使用和区分大小写。
- 目录(Directory):目录/文件夹可以线性或分层方式存储文件,同时维护该目录或子目录中包含的所有文件的索引表。
- 元数据(Metadata):对于存储的每个文件,文件系统存储有关该文件存在的各种信息,例如其数据长度、访问权限、设备类型、修改的日期时间和其他属性。这称为元数据。
- 实用工具(Utilities):文件系统提供用于初始化、删除、重命名、移动、复制、备份、恢复和控制文件和文件夹访问的功能。
- 设计(Design):由于其实现,文件系统对它们可以存储的数据量有限制。
几个关键术语:
- Journaling:Journaling file systems 保存一个称为
journal
的日志,该日志跟踪对文件所做的更改,但尚未永久提交到磁盘,以便在系统故障时,可以恢复丢失的更改。 - 版本控制(Versioning):版本控制系统(Versioning file systems)存储以前保存的文件版本,即文件的副本基于以前对磁盘的提交以分钟或每小时的方式存储以创建备份。
- 索引节点(inode):索引节点是基于一些元数据(文件大小、权限、所有权以及文件和目录的位置)的任何文件或目录的实现。
1.2 文件系统的类型
文件系统是操作系统用于在存储设备上存储、组织和管理文件和目录的方法。一些常见的文件系统类型包括:
- ext (Extended File System):扩展文件系统,它于 1992 年实现,是第一个专门为 Linux 设计的文件系统。它是 ext 系列文件系统的第一个成员。
- ext2:第二个扩展是在1993年开发的。它是一种非日志文件系统,最好与闪存驱动器和 SSD 一起使用。解决了访问时间戳分离、索引节点修改和数据修改的问题。由于未记录(journal),因此在启动时加载速度很慢。
- Xiafs:同样是在 1993 年开发的,这个文件系统的功能和功能不如 ext2,并且在任何地方都不再使用。
- ext3:1999年开发的第三个ext是一个日志文件系统。它是可靠的,与 ext2 不同,如果文件系统在不干净关闭后处于不一致状态,它可以防止系统启动时出现长时间延迟。使它比 ext2 更好且不同的其他因素是在线文件系统增长和大型目录的 HTree 索引。
- JFS (Journaled File System):日志文件系统,最初的JFS最初由IBM于1990年创建,1999年被开源为Linux实现。JFS 在不同类型的负载下表现良好,但由于 2006 年发布的 ext4 提供了更好的性能,因此不再常用。
- ReiserFS:它是2001年开发的日志文件系统。尽管存在早期的问题,但它将尾部包装作为一种减少内部碎片的方案。它使用 B+ 树,在目录查找和更新中提供的时间少于线性。在 6.4 版之前,它是 SUSE Linux 中的默认文件系统,直到 2006 年切换到 ext3 的 10.2 版。
- XFS:XFS 是一个 64 位日志文件系统,于 2001 年移植到 Linux。它现在充当许多 Linux 发行版的默认文件系统。它提供了快照、在线碎片整理、稀疏文件、可变块大小和出色容量等功能。它还擅长并行 I/O 操作。
- SquashFS:此文件系统开发于 2002 年,是只读的,仅用于需要低开销的嵌入式系统。
- Reiser4:它是 ReiserFS 的增量模型。它是在2004年开发的。但是,它在许多 Linux 发行版上并未被广泛调整或支持。
- ext4:2006年开发的第四个ext是一个日志文件系统。它与 ext3 和 ext2 向后兼容,并提供其他一些功能,其中一些是持久预分配、无限数量的子目录、元数据校验和和大文件大小。ext4 是许多 Linux 发行版的默认文件系统,并且还与 Windows 和 Macintosh 兼容。
- btrfs (Better/Butter/B-tree FS):它是在2007年开发的。它提供了许多功能,例如快照,驱动器池,数据清理,自我修复和在线碎片整理。它是 Fedora 工作站的默认文件系统。
- bcachefs:这是一个写入时复制文件系统,于 2015 年首次发布,目标是性能优于 btrfs 和 ext4。其功能包括完整的文件系统加密、本机压缩、快照和 64 位校验求和。
- 其他:Linux还支持NTFS和exFAT等操作系统的文件系统,但这些不支持标准的Unix权限设置。它们主要用于与其他操作系统的互操作性。
- FAT (File Allocation Table):文件分配表,旧版本的 Windows 和其他操作系统使用的较旧文件系统。
- NTFS (New Technology File System):新技术文件系统,Windows使用的现代文件系统。它支持文件和文件夹权限、压缩和加密等功能。
- HFS (Hierarchical File System):分层文件系统,macOS 使用的文件系统。
- APFS (Apple File System):苹果为其Mac和iOS设备推出的新文件系统。
Parameters | ext | ext2 | Xiafs | ext3 | JFS | ReiserFS | XFS | Reiser4 | ext4 | btrfs |
---|---|---|---|---|---|---|---|---|---|---|
Max. filename length(bytes) | 255 | 255 | 248 | 255 | 255 | 255 characters | 255 | 3976 | 255 | 255 |
Allowable characters in directory entries(Any byte) | except NUL | except NUL, / | except NUL | except NUL or / | Any Unicode except NUL | except NUL or / | except NUL | except NUL, / | except NUL, / | except NUL, / |
Max. pathname length | Undefined | Undefined | Undefined | Undefined | Undefined | Undefined | Undefined | Undefined | Undefined | Undefined |
Max. file size | 2 GB | 16GB – 2TB | 64MB | 16GB – 2TB | 4PB | 8TB | 8EB | 8TB (on x86) | 16GB – 16TB | 16EB |
Max. volume size | 2 GB | 2TB – 32TB | 2GB | 2TB – 32TB | 32PB | 16TB | 8EB | – | 1EB | 16EB |
Max. no. of files | – | – | – | – | – | – | – | – | 2^32 | 2^64 |
Metadata only journaling | No | No | No | Yes | Yes | Yes | Yes | No | Yes | No |
Compression | No | No | No | No | No | No | No | Yes | No | Yes |
Block sub-allocation | No | No | No | No | Yes | Yes | No | Yes | No | Yes |
Online grow | No | No | – | Yes | No | Yes | Yes | Yes | Yes | Yes |
Encryption | No | No | No | No | No | No | No | Yes | Yes(experimental) | No |
Checksum | No | No | No | No | No | No | Partial | No | Partial | Yes |
CentOS 7.9 文件名称字符长度、文件路径长度在 /usr/include/linux/limits.h
,可以看到文件名最大长度 NAME_MAX
、文件路径最大长度 PATH_MAX
:
1 | // /usr/include/linux/limits.h |
参考:
- Linux File System
- File Systems in Operating System
- 04-A.2: Linux File Systems
- Introduction to Linux A Hands on Guide
2 分区(Partitions)
这一原则可以追溯到 Linux 没有日志文件系统、电源故障可能导致灾难的时代。 分区的使用仍然是出于安全性和稳健性的原因,因此系统某一部分的破坏并不意味着整个计算机都处于危险之中。 这是目前分区最重要的原因。
一个简单的示例:用户创建一个脚本、程序或 Web 应用程序来开始填充磁盘。 如果磁盘仅包含一个大分区,则当磁盘已满时整个系统将停止运行。 如果用户将数据存储在单独的分区上,则只有该(数据)分区会受到影响,而系统分区和可能的其他数据分区将继续运行。
请注意,日志文件系统(Journaled file system)只能在断电和存储设备突然断开连接的情况下提供数据安全性。 这不能保护您的数据免受文件系统中的坏块和逻辑错误的影响。 在这些情况下,您应该使用 RAID(廉价磁盘冗余阵列)解决方案。
2.1 分区布局和类型
一个硬盘可以划分多个分区,也可以通过软件将一个分区分布在多个硬盘上。在安装过程中,可以使用特定于发行版的工具(通常是直接的图形界面)或 fdisk
(用于创建分区并设置其属性的基于文本的工具)来定义自己的分区布局。
Linux系统上有两种主要分区:
- 数据分区(data partition):正常的 Linux 系统数据,包括根分区,包含系统启动和运行的所有数据。
- 交换分区(swap partition):扩展计算机的物理内存,额外的硬盘内存。
大多数 Linux 系统在安装时使用 fdisk 来设置分区类型。 标准 Linux 分区的 Swap分区号为 82,数据分区号为 83,可以是日志分区(ext3
)或普通分区(ext2
,在旧系统上)。 如果您忘记了这些值,fdisk 实用程序有内置帮助。除了这两种之外,Linux 还支持各种其他文件系统类型,例如相对较新的 Reiser 文件系统、JFS、NFS、FATxx 以及其他(专有)操作系统上本机可用的许多其他文件系统。标准根分区(用单个正斜杠/表示)包含系统配置文件、最基本的命令和服务器程序、系统库、一些临时空间和管理用户的主目录。
在 Linux 上,您几乎永远不会看到诸如“内存不足,请先关闭一些应用程序并重试”之类的恼人消息,因为有额外的内存。 到目前为止,Swap 或虚拟内存过程早已被 UNIX 世界之外的操作系统所采用。
硬盘的其余部分通常分为数据分区,尽管所有非系统关键数据可能都驻留在一个分区上,例如当您执行标准工作站安装时。 当非关键数据被分离在不同的分区上时,通常会遵循一定的模式:
- 用户程序分区(
/usr
) - 包含用户个人数据的分区(
/home
) - 用于存储临时数据(如打印队列和邮件队列)的分区(
/var
) - 第三方和额外软件的分区(
/opt
)
在服务器上,系统数据往往与用户数据分开。 提供服务的程序与该服务处理的数据保存在不同的位置。 将在此类系统上创建不同的分区:
- 包含启动机器所需的所有数据的分区(
/boot
) - 包含配置数据和服务器程序的分区(
/etc
) - 包含服务器数据的一个或多个分区,例如数据库表、用户邮件、ftp 存档等(
/srv
) - 包含用户程序和应用程序的分区(
/opt
) - 一个或多个用于用户特定文件(主目录)的分区(
/home
) - 一个或多个交换分区(虚拟内存)
2.2 挂载的概念
所有的分区都需要通过挂载点(mount point)附加到(attach)系统当中,挂载点定义了一个特定数据集(a particular data set )在文件系统中的位置(实际上挂载点就是我们在系统上看到的被挂载的目录)。 通常,所有分区都通过根分区连接。 在根分区(用斜杠 / 表示)上创建目录, 根目录下的子空目录将是附加分区的地方。
示例:给定一个包含以下目录的分区:
1 | videos/ cd-images/ pictures/ |
管理员可以使用 mount
命令将此分区附加到文件系统中名为 /opt/media
的目录中。 为此,系统管理员必须确保系统上存在目录 /opt/media
。 最好是一个空目录。 使用 mount
命令挂载完成后,当查看以前的空目录 /opt/media
的内容时,它将包含已安装介质(硬盘或硬盘分区、CD、DVD、闪存卡、USB 或其他存储设备)上的文件和目录 videos/
、 cd-images/
、 pictures/
。
在系统启动期间,所有分区都会被挂载,按照文件 /etc/fstab
中描述挂载。 某些分区默认情况下不会安装(mount),例如,如果它们没有持续连接到系统,例如数码相机使用的存储。 如果配置良好,一旦系统发现设备已连接,设备就会被安装,或者它可以是用户可安装的,即您不需要成为系统管理员即可将设备连接到系统或从系统中分离。
在正在运行的系统上,可以使用 df -h
命令(代表磁盘已满或磁盘空闲)显示有关分区及其安装点的信息。 在 Linux中,df
是 GNU 软件,并且支持 -h
等人类可读选项,大大提高了可读性。
df
命令仅显示有关活动非交换分区(active non-swap)的信息。 这些可以包括来自其他网络系统的分区,如下例所示,其中 /home
目录是从网络上的文件服务器安装的,这是企业环境中经常遇到的情况。可以看到,挂载点就是被挂载的目录。
1 | [root@centos7 /] |
查看当前目录位于哪个分区?使用 .
参数:
1 | [root@centos7 /] |
2.3 文件索引节点 inode
每个分区都有自己的文件系统。 将所有这些文件系统想象在一起,我们可以形成整个系统的树形结构的想法,但它并不那么简单。 在文件系统中,文件由索引节点表示(inode
),索引节点是一种序列号,其中包含有关构成文件的实际数据的信息:该文件属于谁,以及它位于硬盘上的位置。
每个分区都有自己的一组 inode
; 在具有多个分区的系统中,可以存在具有相同索引节点号的文件。
通常是在初始系统安装过程中或向现有系统添加额外磁盘时,每个分区会创建固定数量的索引节点。 此数字是分区上所有文件的最大文件数量(包括目录、特殊文件、链接等类型文件)。 我们通常指望每 2 到 8 KB 的存储空间有 1 个 inode
。
创建新文件时,它会获得一个空闲的索引节点。 该 inode 中有以下信息:
- 文件的所有者和组所有者
- 文件类型(常规、目录…)
- 文件的权限
- 创建、上次读取和更改的日期和时间
- 索引节点被更改的日期和时间
- 指向此文件的链接数量
- 文件大小
- 文件数据实际地址
索引节点中唯一不包含的信息是文件名和目录。 这些信息(文件名、所属目录)存储在特殊目录中。 通过比较文件名和索引节点号(inode numbers),系统可以构建用户理解的树形结构。 用户可以使用 ls -i
选项显示 inode
编号。 索引节点(inode
)在磁盘上有自己独立的空间。
1 | [root@centos7 /] |
关于 inode
结构的定义和管理,后续开发篇文章再具体分析。
更多内容可阅读《鸟哥 Linux 私房菜第四版》。
3 目录结构
Filesystem Hierarchy Standard (FHS) 定义了类 Unix 操作系统中的目录结构和目录内容(标准),它还定义了许多文件类型和目录的名称、位置和权限。 它由 Linux 基金会维护,最新版为 3.0。Linux 使用这种标准来组织目录结构(之前学习过 System V AMD64 ABI 介绍了调用约定、对象文件格式、可执行文件格式、动态链接语义等规范标准)。
Linux 目录结构和 Windows 一样是树形结构,但是有所不同,Windows 下使用 C
、D
等盘符表示根目录;Linux 下只有一个根目录 /
。
先登录到 CentOS 7.9 系统:
1 | > ssh root@10.211.55.28 |
登录系统后,一般会默认在 ~
当前目录下,即 /home/user
,如果是 root 用户,则会在 /root
目录下。
有两种逻辑方法来对目录下的文件进行分类:
- shareable vs. unshareable。sharesable:可由本地和远程主机访问,如
/home
下的文件;unshareable:文件仅在本地可用,如/dev
下的文件。 - variable vs. static。variable:可以随时更改;static:没有系统管理员权限的话不可以更改的文件,如二进制文件、库文件等。
为了达到这个目的,通常情况下类 UNIX 系统中,/var
存放 variable
文件,可随时修改,/usr
则以只读方式进行挂载。
根据系统管理员、操作系统和机器的任务,目录结构可能会有所不同。以下是 centOS 7.9 root 用户下的目录结构:
1 | [root@centos7 /] |
目录 | 描述 |
---|---|
/ | 1、The root directory,只有一个根目录,所有的目录和文件都是从根目录开始。如果要使用绝对路径,则必须从根目录 / 开始,如 /usr/src/kernels 。2、只有 root 用户可以在 / 目录下创建目录和文件。3、应用程序不允许在 / 目录下创建文件夹或文件。要创建文件夹最好是在 /home/user 下创建。 |
/bin | 1、是 Binaries (二进制文件)的缩写,包含了系统管理员和用户都可能使用的命令,如 ls 、more 等。2、这个目录包含在 PATH 系统变量里,使用ls 时系统会去 /bin 目录下查找是不是有 ls 这个程序。3、可以看到 /bin 是 /usr/bin 的一个链接(快捷方式)。 |
/sbin | 1、是 Super User Binaries (超级用户的二进制文件)的缩写,这里存放的是系统管理员使用的系统管理程序。即 root 用户可以执行命令的存放地,普通用户无权限使用。/usr/local/sbin 也有部分本地安装的系统管理程序。2、包含除了 /bin 中之外其他的启动、还原、恢复和/或修复系统所必需的二进制文件。3、可以看到 /sbin 是 /usr/sbin 的一个链接(快捷方式)。 |
/home | 1、普通用户的家目录,格式是 /home/用户名 ,每个非 root 用户登录系统后都会在 /home/用户名 目录下,bash 命令可以使用 ~ 表示该目录。该目录存放普通用户个人的数据。2、建议每个用户应该在 /home/user 下创建自己的文件或目录,而不是在 /home 下。 |
/root | 1、root 用户的家目录(root home directory),也是超级权限者用户家目录。root 用户登录系统后,位于该目录下。 2、注意 / 根目录不是 /root root 用户的家目录。 |
/etc | 1、系统级配置目录,存放了系统所有程序配置方面的文件,用户级的配置文件在 /home/user/ 下。/etc 子目录中,而不是直接存放在 /etc 目录下面。2、Startup 和 shutdown 脚本也在该目录下。 3、它不应包含任何二进制文件;如果存在任何二进制文件,请将它们移到 /usr/bin/ 或 /usr/sbin/ 。4、修改过 /etc 下的配置文件,一般都需要重启对应的服务或程序,以使新配置生效。 |
/usr | 1、unix shared resources(共享资源)的缩写,该目录是只读的,允许多台计算机共享。这个文件夹下面的文件是只读的,因为都是和系统相关的文件。 2、从 centOS 7 开始,将根目录下 /bin 、/sbin 、/lib 、/lib64 链接到 /usr 下对应的目录。• /usr/games :存放游戏。• /usr/include :存放标准 C语言的头文件。• /usr/src :存放内核源码、头文件、文档。• /usr/local :存放手动安装的软件。系统管理员在安装软件时会使用这个子目录,在系统更新过程中应安全地覆盖这个子目录。• /usr/share :存放一些共享的数据,比如音乐文件,图片。• /usr/libexec :系统内部应用调用的二进制文件,并不是直接给用户或 shell 脚本使用的。其他程序调用的小型帮助程序。• /usr/etc :不允许使用,/usr 中的程序应该将配置文件放在 /etc 下。• /usr/bin :见 /bin 。• /usr/sbin :见 /sbin 。• /usr/lib :见 /lib 。• /usr/lib64 :见 /lib64 。CentOS 7 引入了新的文件系统结构。目录 /bin 、/sbin 、/lib 和 /lib64 现在嵌套在 /usr 下。 |
/var | variable(可变的)的缩写,包含可变数据文件(variable data files),将经常被修改的目录放在这个目录下,包括各种日志文件数据库电子邮件临时文件等。存放应用程序缓存数据、系统日志文件等。 |
/lib | 32-bit 静态、动态库文件的目录。 64 位 IA64 架构必须将 64 位库放在 /lib 中。/lib 是 /usr/lib 的一个链接(快捷方式)。 |
/lib64 | 64-bit 静态、动态库文件的目录。/lib64 是 /usr/lib64 的一个链接(快捷方式)。 |
/proc | 1、内核和进程信息虚拟文件系统。包括内核/用户进程内存、CPU 信息和硬件配置。 2、是一种伪文件系统(即虚拟文件系统 VFS),存储的是当前内核运行状态的一系列特殊文件,这个目录是一个虚拟的目录,它是系统内存的映射,我们可以通过直接访问这个目录来获取系统信息。 3、这个目录的内容不在硬盘上而是在内存里。 /proc 既不包含文本,也不包含二进制文件,而是虚拟文件。4、这些虚拟文件的大小通常为零字节,即使它们包含大量信息。 5、包含信息如下: • 正在运行的进程信息,每个进程信息在 /proc/{pid} 下。• /proc/cpuinfo :CPU 信息。• /proc/filesystems :列出内核当前已配置的/支持的所有文件系统类型。• /proc/interrupts :目前系统上面的 IRQ 中断号分配状态。• /proc/ioports :包含服务器上设备使用的所有输入和输出地址。• /proc/meminfo :报告 RAM 的使用情况。• /proc/modules :当前正在使用的内核模块。• /proc/mount :已挂载的文件系统。• /proc/stat :该文件跟踪自上次重新启动以来有关系统的各种不同统计信息,例如自系统启动以来页面错误的数量。• /proc/swaps :它包含交换文件信息。参考:《System Administrators Reference Guide—Chapter 2. The proc File System》、Linux Filesystem Hierarchy: Prev Chapter 1. Linux Filesystem Hierarchy、Discover the possibilities of the /proc directory。 |
/dev | 1、存放设备文件,在 Linux 中访问设备的方式和访问文件的方式是相同的。 2、包含两种设备类型的设备节点:连接到系统的设备;内核提供的虚拟设备。 udevd 守护进程根据需要创建和删除/dev/ 中的设备节点。3、大多数设备要么是块设备( block),要么是字符设备(character);然而,存在其他类型的设备,并且可以创建。“块设备”是存储或保存数据的设备,“字符设备”可以被认为是传输或传输数据的设备。例如,软盘驱动器、硬盘驱动器和CD-ROM驱动器都是块设备,而串行端口、鼠标和并行打印机端口都是字符设备。 • /dev/ttyS0 :第一个串行端口(鼠标、调制解调器)。第一个通信端口,COM1。• /dev/lp0 :第一个并行端口(打印机、扫描仪等)。第一个打印机端口,LPT1。• /dev/sda :第一个 SCSI 协议的设备,如 HDD、SATA 硬盘等外部大容量存储设备。• /dev/null :当我们向 /dev/null 发送输出时,内核知道此设备会接收我们所有的输入并丢弃它,因此不会返回任何内容。• /dev/console :系统控制台,在引导期间在此控制台上显示引导和内核消息。• /dev/tty :是一个特殊文件,代表当前进程的终端,它显示与当前 SSH 会话关联的终端。• /dev/tty[0-N] :虚拟控制台,如果您运行的 GUI 系统,N 代表 TTY 编号,则可以从主终端切换到它。默认情况下,/dev/tty0 是默认的虚拟控制台。参考:/dev directory、Linux Filesystem Hierarchy。 |
/boot | linux 内核以及启动引导加载程序所需要的 static 文件,这些文件对于系统正确启动至关重要。注意:不要删除 /boot/ 目录,这样做会使系统无法启动。 |
/mnt | 1、该目录为临时挂载外部存储的文件系统保留(通常为空),如 NFS 文件系统挂载。对于所有可移动存储介质,请使用 /media/ 目录。自动检测到的可移动介质会挂载到 /media 目录中。 2、安装程序不能使用 /mnt 目录。 3、sysadmins(系统管理员)可以在该目录挂在文件系统,普通用户无权挂载和卸载。 |
/media | 1、挂载可移动介质。 2、linux 系统会自动识别一些设备,例如 U 盘、光驱等等,当识别后,Linux 会把识别的设备挂载到这个目录下。 |
/sys | 1、它是现代 Linux 发行版存储的虚拟文件系统,并允许修改连接到系统的设备。 2、 /sys/ 目录用于特定于内核的新 sysfs 虚拟文件系统。随着对内核中热插拔硬件设备的支持增加,/sys/ 目录包含类似于 /proc/ 拥有的信息,但会显示特定于热插拔设备的设备信息的分层视图。• 这是 Linux2.6 内核的一个很大的变化。该目录下安装了 2.6 内核中新出现的一个文件系统 sysfs 。• sysfs 文件系统集成了下面3种文件系统的信息:针对进程信息的 proc 文件系统、针对设备的 devfs 文件系统以及针对伪终端的 devpts 文件系统。• 该文件系统是内核设备树的一个直观反映。 • 当一个内核对象被创建的时候,对应的文件和目录也在内核对象子系统中被创建。 |
/opt | 该目录通常保留用于不属于默认安装的软件和附加软件包。安装到 /opt/ 的软件包会创建一个符合其名称的目录,例如: /opt/packagename/ 。在大多数情况下,此类软件包遵循可预测的子目录结构;大多数软件包将其二进制文件存储在 /opt/ 包名称 /bin/ 中,及其 man page 存储在 /opt/ 包名称 /man/ 中。 |
/run | 1、运行时使用的数据家目录。 2、包含描述系统自引导以来的系统信息数据。必须在引导过程开始时清除此目录下的文件(根据需要删除或截断)。 3、在 Linux 系统中,/run/目录是一个临时文件系统,用于存储在系统启动时运行的进程的运行时数据。它是一个 tmpfs 文件系统,它是一个基于内存的文件系统,存在内存中,不在此盘上,类似于 /proc 。可以快速读取和写入数据,而不会对硬盘进行频繁的读取和写入操作,从而提高系统的性能。4、这个目录的目的曾经由 /var/run 提供,现在 /var/run 链接到 /run 目录。5、/run/ 目录包含了许多重要的文件和目录,其中一些是: • /run/lock/ :用于存储锁文件,确保同一时间只有一个进程可以访问某个共享资源。例如,当一个进程正在使用打印机肘,其他进程将无法访问打印机。• /run/user/ :用于存储用户运行时数据,每个用户都有自己的子目录,例如 /run/user/1000/ 是 UID 为 1000 的用户的运行时数据目录。• /run/systena/ :用于存储 Systemd 运行时数据, 包括 Systemd 进程、Systemd unit 的状态和 Systemd journal 等。• /run/dbus/ :用于存储 D-Bus 运行时数据,包括 D-Bus 进程、D-Bus 会话的地址和 D-Bus 配置文件等。 |
/srv | Service的缩写,包含特定于服务器的服务相关数据。此系统提供的特定于站点(Site-specific)的数据,例如 Web 服务器的数据和脚本、FTP 服务器提供的数据以及版本控制系统的存储库。 |
/tmp | 存放临时文件,系统重启后会被删除。 |
从 centOS 7 开始,系统都是 64-bit,但是兼容 32-bit 的程序。
参考材料:
- 《Filesystem Hierarchy Standard 3.0》
- 《Filesystem Hierarchy Standard 中文版》
- 《Introduction to Linux A Hands on Guide—Chapter 3. About files and the file system》
- Storage Administration Guide—RED HAT ENTERPRISE LINUX 7—File Systems
- Linux File Hierarchy Structure
- Linux Directory Structure
- Filesystem Hierarchy Standard
- 《The Linux Programming Interface Chapter14 File System》
- 《Practical System Programming with C - Pragmatic Example Applications in Linux and Unix-Based Operating Systems Chapter 4 Files and Directories》
4 文件链接
链接文件类似于 Windows 下面的快捷方式,Linux 上可以看成是文件/目录的别名,使用 ls -l
查看时文件类型为 l
。链接文件可以指向任何一个文件/目录,存在的或不存在的文件,或者指向其他文件系统的文件都可以。使用链接文件的好处就是节约磁盘空间、方便文件同步管理(链接文件共享一份磁盘上的文件)。
给一个文件/目录创建链接,可以使用 ln
命令。符号链接文件要遵守文件系统目录/文件的命名规范(使用上当做目录/文件使用即可)。链接有两种类型:软链接、硬链接。
链接类型 | 说明 |
---|---|
硬链接 | Hard link。硬链接文件和源文件共同使用一个文件 i-node,相当于一个文件有不同的名字,但是磁盘上仅有一份文件数据。 实际上,每个常规的文件/目录就是硬链接文件。 使用 ls -l 列出文件属性的第二列即表示文件硬链接的个数(也可以说是别名的个数),1 即表示当前文件,没有其他硬链接。删除硬链接或者源文件时,硬链接数会减一 -1 ,只有当硬链接数为 0 时,才会删除文件的 i-node 和数据块(也就是删除文件)。硬链接和源文件是平等的,包括权限、大小等,但是磁盘仅仅是一份文件。原生的 Linux 文件系统支持给目录创建硬链接,但事实不建议这么做,可能会造成混乱。 1、因为同一文件系统 i-node 的唯一性,所以硬链接只能链接同一文件系统的文件。 2、不能为目录创建硬链接,否则可能会出现混乱或链接环路(A->B, B->A)。 3、增、改、查链接文件的内容即为操作源文件内容。 |
软链接 | Soft link 或 symbolic link。磁盘上一个很小的文件,类似于指针,指向源文件。软链接文件和源文件使用不同的 i-node,所以可以为另外一个文件系统的文件创建软链接。 1、文件名以路径形式命令,指向目标文件/目录。 2、可以跨文件系统,硬链接不可以。 3、可以给目录创建软链接。 4、增、改、查链接文件的内容即为操作源文件内容。 5、源文件删除后,软链接文件虽然存在,但是指向的目标文件已经失效。 6、使用 ls -l 可以看到软链接文件后面有 -> ,指向链接的源文件。硬链接文件没有 -> 。 |
命令格式:
1 | ln [参数][源文件或目录][链接文件或目录] |
4.1 硬链接
创建硬链接,并查看文件属性。
1
2
3
4
5
6
7
8// 创建文件,并写入内容
[alvin@centos-7 ~]$ touch source.txt; echo "Hello, this is test text." >> source.txt
// 创建硬链接
[alvin@centos-7 ~]$ ln source.txt target.txt
[alvin@centos-7 ~]$ ll -ih
67381300 -rw-rw-r--. 2 alvin alvin 26 Jul 28 21:56 source.txt
67381300 -rw-rw-r--. 2 alvin alvin 26 Jul 28 21:56 target.txt可以看到第三列的硬链接数量为
2
,并且硬链接文件target.txt
上看不出来是一个链接,和正常文件看起来一样,这是因为每个常规的文件/目录就是硬链接文件。硬链接文件和源文件的 i-node 相同,都是
67381300
。删除源文件
source.txt
,观察变化。1
2
3
4
5
6
7[alvin@centos-7 ~]$ rm source.txt
[alvin@centos-7 ~]$ ll -ih
67381300 -rw-rw-r--. 1 alvin alvin 26 Jul 28 21:56 target.txt
// 可以看到硬链接文件还在
[alvin@centos-7 ~]$ cat target.txt
Hello, this is test text.
4.2 软链接
创建软链接,并查看文件属性。
1
2
3
4
5
6
7
8// 硬链接文件实际上就是一个源文件
[alvin@centos-7 ~]$ ln target.txt source.txt
[alvin@centos-7 ~]$ ll -ih
total 8.0K
67381300 -rw-rw-r--. 2 alvin alvin 26 Jul 28 21:56 source.txt
67383526 lrwxrwxrwx. 1 alvin alvin 10 Jul 28 22:06 target_soft.txt -> source.txt
67381300 -rw-rw-r--. 2 alvin alvin 26 Jul 28 21:56 target.txt可以看到源文件和软链接文件拥有不同的 i-node,还可以看到软链接文件和源文件是两个独立的文件,大小不一样。而硬链接文件和源文件是同一个文件,属性、大小肯定是一样的。
软链接文件是一个文件,拥有自己的 i-node。
1
2
3
4[alvin@centos-7 ~]$ echo "Something was added." >> target_soft.txt
[alvin@centos-7 ~]$ cat target_soft.txt
Hello, this is test text.
Something was added.删除源文件。
1
2
3
4
5
6
7
8
9[alvin@centos-7 ~]$ rm -f source.txt
[alvin@centos-7 ~]$ ll -ih
total 4.0K
67383526 lrwxrwxrwx. 1 alvin alvin 10 Jul 28 22:06 target_soft.txt -> source.txt
67381300 -rw-rw-r--. 1 alvin alvin 47 Jul 28 22:16 target.txt
[alvin@centos-7 ~]$ cat target_soft.txt
cat: target_soft.txt: No such file or directory可以看到此时的软链接已经链接不到源文件了。但是软链接文件还在,试着往软链接文件写入内容看看。
删除源文件后,向软链接文件写入内容,观察变化。
1
2
3
4
5
6
7[alvin@centos-7 ~]$ echo "The source file has been deleted, this is added to the soft link file." > target_soft.txt
[alvin@centos-7 ~]$ ll -ih
total 8.0K
67146876 -rw-rw-r--. 1 alvin alvin 71 Jul 28 22:24 source.txt
67383526 lrwxrwxrwx. 1 alvin alvin 10 Jul 28 22:06 target_soft.txt -> source.txt
67381300 -rw-rw-r--. 1 alvin alvin 47 Jul 28 22:16 target.txt可以看到系统通过软链接指向为文件名称,创建了新文件
source.txt
。注意观察source.txt
和target.txt
文件的 i-node 是不相同的、大小也不相同,所以这里是新建了文件。1
2
3
4
5
6
7[alvin@centos-7 ~]$ cat source.txt
The source file has been deleted, this is added to the soft link file.
// 可以看到两个文件是不相同的
[alvin@centos-7 ~]$ cat target.txt
Hello, this is test text.
Something was added.
那不可以删除文件时连链接在该文件上的软/硬链接也删除??留个坑,以后填。
5 PATH 环境变量
环境变量相关内容还可参考《程序员的自我修养–链接、装载与库 8.5 》。
5.1 介绍
当您希望系统执行命令时,您几乎不需要提供该命令的完整路径。 例如,我们知道 ls
命令在 /bin
目录中(用which -a ls
查看),但我们不必输入命令 /bin/ls
让计算机列出当前目录的内容。
PATH
环境变量负责处理这个问题。 该变量列出了系统中可以找到可执行文件的目录,从而节省了用户大量键入和记忆命令位置的时间。 因此,PATH
里自然包含许多含有 /bin
的目录。echo
命令用于显示变量 PATH
的内容($
):
1 | [root@centos7 /] |
注意:Linux 中的 :
相当于 Windows 中的 ;
。
解释:如上所示,系统在目录 /usr/local/sbin
、/usr/local/bin
、/usr/sbin
、/usr/bin
和 /root/bin
中搜索所需的程序。 一旦找到匹配项,搜索就会停止,即使并未搜索到路径中的每个目录。 这可能会导致奇怪的情况。 在下面的第一个示例中,用户知道有一个名为 sendms 的程序可以发送 SMS 消息,并且同一系统上的另一个用户可以使用它,但她不能。 区别在于 PATH 变量的配置:
1 | [jenny@blob jenny]$ sendsms |
在下一个示例中,用户想要调用 wc
(字数统计)命令来检查文件中的行数,但没有任何反应,他必须使用 Ctrl+C 组合中断操作:
1 | jumper:~> wc -l test |
由于此例中 wc
是用户自己写的程序,系统首先在 PATH
路径下搜索到该程序就执行了,但是用户写的程序可能参数无法识别,导致了这样的问题。要解决此问题,有多种方法(在 UNIX/Linux 中总是有多种方法来解决问题):一种答案可能是重命名用户的 wc 程序,或者用户可以给出他想要的确切命令的完整路径, 可以通过使用 which
命令的 -a
选项来找到它。如果用户更频繁地使用其他目录中的程序,他可以临时更改 PATH
环境变量,使用 export
,在最后加 :
进行分割,然后填上绝对路径:
1 | [root@centos7 /] |
注意:修改环境变量只是临时的更改。请注意,在 shell 中使用 export
命令时,更改是临时的,并且仅对此会话有效(直到您注销)。 打开新会话,即使当前会话仍在运行,也不会在新会话中产生新路径。 我们将在第 7.2 节中看到如何通过将这些行添加到 shell 配置文件来永久地对环境进行此类更改。
5.2 环境变量临时修改
系统中有个很多环境变量,可以使用 printenv
、env
命令查看系统当前配置的所有环境变量(echo
命令可以查看指定名称的环境变量)。环境变量由 shell 进行管理,供系统中所有进程共享。环境变量名按照惯例都使用大写。
使用 export
可以在当前会话窗口临时指定名称环境变量最后添加新的环境变量,其他会话窗口不会使用该环境变量新值,或当前会话注销后该环境变量就失效。
1 | export 变量名=$变量名:新值 |
查看当前环境变量:
1 | [root@centos7 /] |
TERM
:正在使用的终端类型。在文本模式下,这将是 linux 终端仿真,在图形模式下,您可能会使用 xterm。SHELL
:shell 终端类型。PATH
:可执行程序的环境变量路径HOME
:当前用户的家目录。PWD
:指示当前目录。HOSTNAME
:主机名。
5.3 环境变量永久修改
修改系统配置文件,可以达到永久修改环境变量的作用。系统配置文件一般以 .xxxrc
后缀名存在,如 /root/.bashrc
。
如果是使用 bash
shell 的话,当前用户对应的配置在 ~/.profile
、~/.bash_profile
、~/.bash_login
、~/.bash_logout
中。全局的环境变量在 /etc/profile
文件中设置。
如上述的 $PATH
路径就可以在 ~/.bash_profile
中添加。
1 | [root@centos7 /] |