01 Linux 哲学核心思想 - 一切皆文件
一切皆文件的含义
- 一切皆文件:Everything is a file.
- 无论是目录、字符设备、块设备、套接字、进程、线程,均可通过
fopen()、fread()、fwrite()、fclose()等函数进行处理 - Linux 系统屏蔽了硬件的区别,将所有设备都抽象为文件,以文件的形式进行保存和管理,给用户提供统一的接口
- 可跨文件系统执行文件读写等操作
文件:在 Linux 中,文件不仅仅是我们通常理解的文本或数据文档,它还包括设备、管道、套接字等。
- 设备文件:硬件设备(如硬盘、终端、网络接口等)都被映射为文件,通常位于
/dev目录中。例如,硬盘设备文件可能是/dev/sda,终端设备文件可能是/dev/tty1。 - 目录:目录本身也是一种文件,它存储了该目录下的文件名及其相关的元数据。
- 进程:每个运行中的进程都在
/proc目录中对应一个文件夹,通过这些文件夹,可以查看和操作进程的状态、内存使用、打开的文件描述符等信息。 - 管道和套接字:用于进程间通信的管道(pipe)和网络通信使用的套接字(socket)也可以作为文件来访问。这些通常位于
/dev或/proc目录下,或者通过命名管道创建。 - 配置文件:系统配置、用户配置等信息通常以文本文件的形式存在,便于编辑和管理。
- 设备文件:硬件设备(如硬盘、终端、网络接口等)都被映射为文件,通常位于
统一视角:Linux 将几乎所有资源(如硬件设备、输入/输出接口、通信接口等)都视为文件。这意味着,对这些资源的操作可以通过标准的文件操作接口(打开、读取、写入、关闭)来完成。
文件系统:所有这些“文件”都组织在文件系统中,即使它们并不实际存储在硬盘上。
文件分类
| 文件类型 | 符号 | 描述 |
|---|---|---|
| 常规文件(Regular File) | - | 普通的数据文件,可以包含文本、二进制数据或程序等。 |
| 目录(Directory) | d | 包含其他文件的容器,实际上也是一种文件。 |
| 字符设备文件(Character Device) | c | 提供对设备的串行访问,如键盘、鼠标等。 |
| 块设备文件(Block Device) | b | 表示设备的随机访问接口,如硬盘。 |
| 管道文件(FIFO/Named Pipe) | p | 用于进程间通信的特殊文件,数据进一端出另一端。 |
| 符号链接文件(Symbolic Link) | l | 引用另一个文件的路径链接。 |
| 套接字文件(Socket) | s | 用于进程间或网络间的通信,支持数据交换。 |
ls -lha中输出列表信息的首字符,即代表该文件的类型
bash
➜ ~ ls -lha /
total 76K
dr-xr-xr-x. 20 root root 4.0K Aug 9 06:25 .
dr-xr-xr-x. 20 root root 4.0K Aug 9 06:25 ..
dr-xr-xr-x. 2 root root 4.0K Jun 25 22:23 afs
-rw-r--r-- 1 root root 0 Jul 23 09:11 .autorelabel
lrwxrwxrwx 1 root root 7 Jun 25 22:23 bin -> usr/bin
dr-xr-xr-x. 5 root root 4.0K Jul 23 11:25 boot
drwxr-xr-x 2 root root 4.0K Feb 9 2022 data
drwxr-xr-x 19 root root 3.1K Jun 25 22:23 dev
drwxr-xr-x. 93 root root 4.0K Jul 31 16:07 etc
drwxr-xr-x. 3 root root 4.0K Jun 25 22:23 home
lrwxrwxrwx 1 root root 7 Jun 25 22:23 lib -> usr/lib
lrwxrwxrwx 1 root root 9 Jun 25 22:23 lib64 -> usr/lib64
drwx------. 2 root root 16K Jan 20 2022 lost+found
drwxr-xr-x. 2 root root 4.0K Jun 25 22:23 media
drwxr-xr-x. 2 root root 4.0K Jun 25 22:23 mnt
drwxr-xr-x. 2 root root 4.0K Jun 25 22:23 opt
dr-xr-xr-x 190 root root 0 Jul 23 09:11 proc
dr-xr-x---. 9 root root 4.0K Aug 9 06:25 root
drwxr-xr-x 28 root root 1000 Jul 23 12:19 run
lrwxrwxrwx 1 root root 8 Jun 25 22:23 sbin -> usr/sbin
drwxr-xr-x. 2 root root 4.0K Jun 25 22:23 srv
dr-xr-xr-x 13 root root 0 Jul 23 11:22 sys
drwxrwxrwt. 8 root root 4.0K Aug 9 06:24 tmp
drwxr-xr-x. 12 root root 4.0K Jul 23 11:22 usr
drwxr-xr-x. 19 root root 4.0K Jul 23 11:22 var-rw-r--r--:常规文件(Regular File),这里的-表示常规文件。drwxr-xr-x:目录(Directory),这里的d表示这是一个目录。crw-rw----:字符设备文件(Character Device),这里的c表示字符设备。brw-rw----:块设备文件(Block Device),这里的b表示块设备。prw-r--r--:管道文件(FIFO/Named Pipe),这里的p表示管道。lrwxrwxrwx:符号链接文件(Symbolic Link),这里的l表示符号链接。srwxr-xr-x:套接字文件(Socket),这里的s表示套接字。
在 Linux 操作系统中,有一个核心哲学理念——“一切皆文件”。这意味着几乎所有的系统资源和设备,无论是物理设备、进程、网络接口、配置项等,都可以被看作文件来进行操作。这种设计带来了统一的接口和简洁的操作方式,使得 Linux 系统变得非常灵活和强大。以下是对这一概念的详细介绍:
普通文件
- 定义:普通文件是用户最常接触到的文件类型,通常包括文本文件、可执行文件、脚本文件等。
- 特点:普通文件包含数据,可以被读取、写入、修改。文件系统为这些文件提供了标准的接口,如
open、read、write等操作。
目录 Directory
- 定义:目录是用来存储文件和子目录的特殊文件。
- 特点:目录本质上也是一个文件,但它存储的是文件名及其对应的 inode 信息。通过目录文件,可以方便地组织和管理系统中的文件结构。
- 操作:可以通过
ls列出目录内容,通过cd切换目录,通过mkdir创建新目录等。
设备文件 Device Files
- 定义:设备文件是对硬件设备的抽象,如硬盘、键盘、显示器等。
- 类型:设备文件分为字符设备和块设备:
- 字符设备文件:一次处理一个字符数据,如键盘、串口设备。典型的字符设备文件在
/dev目录下,如/dev/tty。 - 块设备文件:一次处理大块数据,通常是存储设备,如硬盘。典型的块设备文件有
/dev/sda等。
- 字符设备文件:一次处理一个字符数据,如键盘、串口设备。典型的字符设备文件在
- 特点:设备文件提供了对设备的标准化访问方式,可以像读写普通文件一样访问这些设备。
管道 Pipes
- 定义:管道文件是一种特殊的文件类型,用于在两个进程之间传递数据。
- 类型:
- 匿名管道(Anonymous Pipes):只能在有亲缘关系的进程之间使用。
- 命名管道(Named Pipes):通过一个文件名存在于文件系统中,可以在无亲缘关系的进程间传递数据,典型例子如
FIFO文件。
- 特点:数据在管道中是线性流动的,写入的数据只能被一次性读取。
套接字 Sockets
- 定义:套接字文件是一种用于网络通信的特殊文件类型。
- 特点:套接字文件用于实现进程之间的网络通信,支持多种协议(如 TCP、UDP)。在文件系统中,套接字文件通常存储在
/var/run/或/tmp/目录下。 - 操作:可以使用
socket系统调用创建套接字,通过bind、listen、accept等调用进行网络通信。
符号链接 Symbolic Links
- 定义:符号链接是指向另一个文件或目录的特殊文件。
- 特点:符号链接类似于 Windows 系统中的快捷方式,它不包含实际数据,而是指向目标文件。通过
ln -s命令创建符号链接。
进程与文件
- 定义:在 Linux 中,进程也可以通过文件接口来管理和操作。
- 特点:每个进程在
/proc文件系统下都有对应的目录,里面包含了该进程的各种信息,如status、cmdline、fd(文件描述符)等。这些信息都以文件的形式存在,可以通过读取这些文件来了解进程的状态。
虚拟文件系统 Virtual Filesystem
- 定义:虚拟文件系统(如
/proc和/sys)是内核提供的接口,用于访问内核数据结构和系统状态。 - /
proc:提供进程信息和系统状态,如 CPU 信息、内存使用情况等。 /sys:主要用于查看和控制硬件设备及驱动相关的参数。
利用文件类型符号进行数据过滤
bash
# 过滤以 - 开头的文件,即常规文件
ls -lha ./ | grep "^-"Linux bash 脚本可以通过:
| 参数 | 描述 |
|---|---|
-e | 检查文件是否存在,不论文件类型是什么。 |
-f | 判断文件是否为普通文件,如文本文件、二进制文件等。 |
-d | 检查文件是否为目录(文件夹)。 |
-L | 判断文件是否为符号链接(软链接)。 |
-S | 判断文件是否为套接字文件,一般在网络通信中使用。 |
-c | 检查文件是否为字符设备文件,如终端、串口等。 |
-b | 判断文件是否为块设备文件,如硬盘、U 盘等。 |
bash
#!/bin/bash
FILE_PATH="/tmp/testfile"
check_file() {
if [ -e "$FILE_PATH" ]; then
echo "文件存在:$FILE_PATH"
else
echo "文件不存在:$FILE_PATH"
fi
}
check_file
touch "$FILE_PATH"
check_filebash
#!/bin/bash
FILE_PATH="/tmp/testfile"
check_regular_file() {
if [ -f "$FILE_PATH" ]; then
echo "这是一个普通文件:$FILE_PATH"
else
echo "不是普通文件:$FILE_PATH"
fi
}
check_regular_filebash
#!/bin/bash
DIR_PATH="/tmp/testdir"
check_directory() {
if [ -d "$DIR_PATH" ]; then
echo "这是一个目录:$DIR_PATH"
else
echo "不是目录:$DIR_PATH"
fi
}
check_directory
mkdir "$DIR_PATH"
check_directorybash
#!/bin/bash
FILE_PATH="/tmp/testfile"
LINK_PATH="/tmp/testlink"
check_symlink() {
if [ -L "$LINK_PATH" ]; then
echo "这是一个符号链接:$LINK_PATH -> $(readlink -f "$LINK_PATH")"
else
echo "不是符号链接:$LINK_PATH"
fi
}
check_symlink
ln -s "$FILE_PATH" "$LINK_PATH"
check_symlinkbash
#!/bin/bash
SOCKET_PATH="/tmp/testsocket"
check_socket() {
if [ -S "$SOCKET_PATH" ]; then
echo "这是一个套接字文件:$SOCKET_PATH"
else
echo "不是套接字文件:$SOCKET_PATH"
fi
}
check_socket
if [ -e "$SOCKET_PATH" ]; then
rm "$SOCKET_PATH"
fi
socat -d TCP-LISTEN:12345,reuseaddr,fork TCP-LISTEN:12346,reuseaddr,fork >/dev/null 2>&1 & # 创建套接字,监听 12345 端口
check_socketbash
#!/bin/bash
CHAR_DEV_PATH="/dev/ttyS0"
check_char_dev() {
if [ -c "$CHAR_DEV_PATH" ]; then
echo "这是一个字符设备文件:$CHAR_DEV_PATH"
else
echo "不是字符设备文件:$CHAR_DEV_PATH"
fi
}
check_char_dev
# 创建字符设备文件
sudo mknod "$CHAR_DEV_PATH" c 4 64 # 4 是主设备号,64 是次设备号
check_char_devbash
#!/bin/bash
BLOCK_DEV_PATH="/dev/sda"
check_block_dev() {
if [ -b "$BLOCK_DEV_PATH" ]; then
echo "这是一个块设备文件:$BLOCK_DEV_PATH"
else
echo "不是块设备文件:$BLOCK_DEV_PATH"
fi
}
check_block_dev
# 创建块设备文件
sudo mknod "$BLOCK_DEV_PATH" b 8 0 # 8 是主设备号,0 是次设备号
check_block_devLinux 系统中常见的目录名称
| 目录名称 | 应放置文件的内容 |
|---|---|
/boot | 系统启动文件,如内核和启动菜单 |
/dev | 设备文件,代表系统中的硬件设备 |
/etc | 系统配置文件和启动脚本 |
/root | 管理员的个人主目录 |
/home | 用户的个人主目录 |
/bin | 基本用户命令,可在单用户模式下使用 |
/lib | 系统共享库,供 /bin 和 /sbin 命令使用 |
/sbin | 系统管理命令,供管理员使用 |
/media | 挂载点目录,用于可移动设备 |
/opt | 第三方应用软件包 |
/srv | 服务数据目录,存放网络服务数据 |
/tmp | 临时文件目录,所有用户均可访问 |
/proc | 虚拟文件系统,提供进程和内核信息 |
/usr/local | 本地安装的软件和应用程序 |
/usr/sbin | 系统管理员使用的非基本管理命令 |
/usr/share | 共享数据,如文档和帮助文件 |
/var | 动态数据,如日志文件和临时文件 |
/lost+found | 文件系统恢复区,存放丢失的文件碎片 |
常见的硬件设备及其文件名称
| 硬件设备 | 文件名称 |
|---|---|
| IDE 设备 | /dev/hd[a-d] |
| NVMe 设备 | /dev/nvme[0-23] |
| SCSI/SATA/U盘 | /dev/sd[a-z] |
| virtio 设备 | /dev/vd[a-z] |
| 软驱 | /dev/fd[0-1] |
| 打印机 | /dev/lp[0-15] |
| 光驱 | /dev/cdrom |
| 鼠标 | /dev/mouse |
| 磁带机 | /dev/st0 或 /dev/ht0 |
常见的文件系统
| 文件系统 | 特点 |
|---|---|
| Ext2 | 最早可追溯到 1993 年,是 Linux 系统的第一个商业级文件系统,基本沿袭了 UNIX 文件系统的设计标准。不包含日志读写功能,数据丢失的可能性大,通常不建议使用,顶多用于 SD 存储卡或 U 盘。 |
| Ext3 | 日志文件系统,预先记录写入动作的细节,然后再进行实际操作,能够在系统异常宕机时避免数据丢失并自动修复错误。硬盘容量较大时,修复时间较长,且不能 100% 保证数据不丢失。 |
| Ext4 | Ext3 的改进版本,是 RHEL 6 系统的默认文件管理系统,支持的存储容量高达 1EB,支持无限多的子目录,能够批量分配 block,极大提高读写效率,主流服务器常用。 |
| XFS | 高性能的日志文件系统,是 RHEL 7/8 的默认文件管理系统,宕机后可快速恢复被破坏的文件,日志功能对计算和存储性能的影响很小,支持的最大存储容量为 18EB。 |