惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

S
Schneier on Security
Security Archives - TechRepublic
Security Archives - TechRepublic
T
Threat Research - Cisco Blogs
G
GRAHAM CLULEY
P
Privacy & Cybersecurity Law Blog
C
CXSECURITY Database RSS Feed - CXSecurity.com
Cisco Talos Blog
Cisco Talos Blog
The Hacker News
The Hacker News
L
Lohrmann on Cybersecurity
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
C
Cyber Attacks, Cyber Crime and Cyber Security
Security Latest
Security Latest
Know Your Adversary
Know Your Adversary
P
Palo Alto Networks Blog
C
Cisco Blogs
AWS News Blog
AWS News Blog
T
Threatpost
L
LINUX DO - 热门话题
Simon Willison's Weblog
Simon Willison's Weblog
Scott Helme
Scott Helme
C
Cybersecurity and Infrastructure Security Agency CISA
T
Tor Project blog
Cyberwarzone
Cyberwarzone
P
Proofpoint News Feed
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
T
The Exploit Database - CXSecurity.com
The Register - Security
The Register - Security
D
Darknet – Hacking Tools, Hacker News & Cyber Security
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
罗磊的独立博客
云风的 BLOG
云风的 BLOG
V
Vulnerabilities – Threatpost
N
News | PayPal Newsroom
Project Zero
Project Zero
NISL@THU
NISL@THU
博客园_首页
MyScale Blog
MyScale Blog
V2EX - 技术
V2EX - 技术
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
F
Full Disclosure
T
Troy Hunt's Blog
Recorded Future
Recorded Future
N
Netflix TechBlog - Medium
P
Privacy International News Feed
H
Hackread – Cybersecurity News, Data Breaches, AI and More
A
Arctic Wolf
C
Check Point Blog
W
WeLiveSecurity
Apple Machine Learning Research
Apple Machine Learning Research
C
CERT Recently Published Vulnerability Notes

蛮荆

如何获取更多的免费服务器 Kubernetes 调度器队列 - 设计与实现 Kubernetes 调度器 - 核心流程 Kubernetes Networking Model & CNI Kubernetes 控制器管理总结 Kubernetes CronJob 设计与实现 Kubernetes Job 设计与实现 Kubernetes HPA 设计与实现 Kubernetes Deployment 滚动更新实现原理 Kubernetes GC 设计与实现 Kubernetes Pod 驱逐 - 设计与实现 Kubernetes Daemonset 设计与实现 Kubernetes ReplicaSet 设计与实现 Kubernetes EndPoint 设计与实现 Kubernetes Informer 设计与实现 降本增效之应用优化 (三) 日志存储与检索 Kubernetes Pod 设计与实现 - 创建流程 Kubernetes 探针设计与实现 Unix 编程艺术名句摘录 Kubernetes - CRI 概述 Golang 编译速度为什么这么快? Kubernetes Pod 设计与实现 - Pause 容器 Kubernetes - kube-proxy 代理模式工程优化 Kubernetes 应用最佳实践 - 优雅关闭长连接 Kubernetes Service 类型和会话亲和性 Kubernetes 为什么需要 Ingress Kubernetes 架构 - 控制平面和数据平面 降本增效之应用优化 (二) 大报表 Go 语言如何获取 CPU 利用率 降本增效之应用优化 (一) Redis 业务规则引擎演变过程简述 微服务中的熔断算法 漏桶算法和令牌桶算法 jsonparser 为什么比标准库的 encoding/json 快 10 倍 ? zap 高性能设计与实现 HTTP Router 算法演进 fastcache 高性能设计与实现 Web 常见的三个安全问题 ants Code Reading Go 线程安全 map 方案选型 布隆过滤器 死锁、活锁、饥饿、自旋锁 sync.Pool Code Reading Go 内存管理概述 Go netpoll Code Reading goroutine 泄漏与检测 time/Timer Code Reading GMP Scheduler Code Reading Go channel 的 15 条规则和底层实现 context.Context Code Reading runtime/HACKING.md Goland 最佳实践 互联网开发与金庸武学 为什么 Redis 6.0 引入多线程模型? Kubernetes 应用最佳实践 - 金丝雀发布 容器中如何正确配置 GOMAXPROCS ? singleflight Code Reading sync.Map Code Reading sync.Cond Code Reading sync.WaitGroup Code Reading sync.RWMutex Code Reading sync.Mutex Code Reading sync.Once Code Reading Go 无锁编程 sync/atomic Code Reading goroutine 交替打印奇偶数 GODEBUG Go 并发模式 Go 汇编 UUID 通用技术选型 Kubernetes 应用最佳实践 - 水平自动伸缩 Go 高性能 Tips fasthttp 为什么比标准库 net/http 快 10 倍 ? 技术文章配图指南 ChatGPT 初体验 Docker 网络原理概览 iptables 的五表五链 Kubernetes 应用最佳实践 - 亲和性和污点容忍度 Go 的反射与三大定律 Docker 官方提供的最佳实践 Go 语言内置的设计模式 HTTP1 到 HTTP3 的工程优化 Kubernetes 应用最佳实践 - Sidecar 模式 Kubernetes 应用最佳实践 - init 容器和钩子函数 为什么 recover 必须在 defer 中调用? 为什么 defer 的执行顺序和注册顺序不同? Go map 设计与实现 Go 切片扩容底层实现 Go 语言中的零拷贝 Go Delve 云原生和边缘计算简介 Kubernetes Pod 服务质量等级 Kubernetes 应用最佳实践 - 探针 Kubernetes 应用最佳实践 - 资源请求和限制 CDN 原理 Kubernetes 应用最佳实践 - 开篇 缓存策略和模式 Go 内存模型 Kubernetes 核心概念 软件版本语义化
为什么 Linux “一切皆文件”
2023-05-19 · via 蛮荆

2023-05-19 操作系统 Linux

概述

在 Linux 中,包括硬件设备、目录、文本文件、二进制文件、输入输出流、套接字、管道、TTY 终端等各种资源都被抽象成文件,并且它们之间没有太大的区别。 每个文件都有一个唯一的路径进行标识,因此可以通过文件系统中的路径来访问和管理这些资源。

一切皆为文件的理念提供了最高级的抽象,开发者只需要使用一套 API 就可以操作 Linux 系统中的绝大部分资源。

一个典型的 Linux 系统的文件结构如下所示:

图片来源: https://tldp.org/LDP/intro-linux/html/sect_03_01.html

常见文件类型

1. 普通文件

普通文件并不单单指文本文件,还包括可执行二进制程序、程序的输入输出等。

2. 目录文件

目录文件包含一组文件的所有者、权限和大小等信息。

3. 设备文件

所有物理设备都是通过设备文件进行访问的,设备文件保存有关特定设备的位置、类型和访问模式等信息,主要分为两种类型: 块设备文件和字符设备文件

块设备文件 用于访问块设备 I/O, 块设备使用的是缓冲 I/O,这意味着数据收集在缓冲区中,直到可以传输整个块为止。

字符设备文件 与字符或原始设备进行无缓冲数据传输,数据传输按照字符逐个进行,单次可以传输多个字符。

此外,某些设备(例如磁盘分区)可以以块设备或字符设备模式访问,每个设备文件对应一种访问模式,因此这种具有多种访问模式的物理设备将具有多个设备文件

设备文件全部位于 dev 目录,执行下面的命令:

输出结果中会逐行输出单个设备文件,第一个字符 b 表示该设备为块设备。

4. 特殊文件

特殊文件用于输入和输出的机制,本质上也是一种 “设备文件”,典型的特殊文件如:

  • /dev/null : 用于丢弃进程的输出流
  • /dev/full : 对该文件进行写入时始终返回相同的错误代码:ENOSPC (表示设备上没有可用空间)
  • /dev/zero : 用于一些需要初始化变量、清空内存或写入特定位模式的应用程序
  • /dev/random : 利用物理过程(例如键盘敲击、鼠标移动、磁盘I/O等)的噪声来收集随机性,并将其整合以产生高质量的随机数。由于这些物理过程本身具有随机性,因此可以确保生成的随机数是真正的随机数,而不是伪随机数
# 查看设备文件
$ ls -l /dev/ | grep -e  "null\|zero"

crw-rw-rw- 1 root root   1,   3 Jun 21 20:39 null
crw-rw-rw- 1 root root   1,   5 Jun 21 20:39 zero
# /dev/null 示例

$ echo "Hello World" > /dev/null
# /dev/full 示例

$ echo: write error: no space left on device
# /dev/zero 示例
# 将 /dev/zero 的输出写入到 text.txt 文件中,并且限制文件的大小为 10MB。
# 由于从 /dev/zero 中读取的所有数据都是零值,因此最终 test.txt 文件中将包含 10MB 的零值字节

$ dd if=/dev/zero of=test.txt bs=1M count=10
# /dev/random 示例
# 从 /dev/random 中读取 16 个字节的随机数据,并转换为一个无符号整数 (十进制表示形式)
# -t u4 参数指定以无符号 4 字节整数形式输出数据
# -An 参数指定不要输出地址信息

$ head -c 16 /dev/random | od -t u4 -An

5. 链接文件

使用 ln 命令创建硬链接和软链接。

# 创建硬链接
$ ln /tmp/abc.txt /tmp/def.txt

# 创建软链接
$ ln -s /tmp/abc.txt /tmp/def.txt

5. 套接字文件

套接字文件是一种特殊类型的文件,用于实现进程间通信 (IPC), 可以看作是网络套接字与本地套接字的混合体。

对于进程间通信,套接字提供了一种简单而强大的方式来传递数据,它们可以在同一台计算机上的进程之间进行通信,也可以在不同计算机上的进程之间进行通信。 套接字文件通常存储在文件系统的特定目录中,例如 /var/run 或 /tmp,通常分为由操作系统系统软件创建的和由应用程序创建的。

6. 命名管道文件

命名管道允许多个进程之间通过一个共享的命名管道文件进行通信,进程可以向管道写入数据,并从管道读取数据,就好像在普通文件中读写数据一样。

查看文件类型

调用 ls 命令时,输出结果中会逐行输出单个文件,第一个字符 表示该文件的类型。

字母 文件类型
- 普通文件
d 目录文件
l 链接文件
c 特殊文件
s 套接字文件
p 命名管道文件
b 块设备文件
# 例如,我们可以查看 /var/run 目录下的文件列表
$ ls -l /var/run

total 60
drwxr-xr-x 2 dnsmasq  nogroup  4096 Jun 20 21:51 dnsmasq
drwx------ 6 root     root     4096 Jun 24 08:09 docker
-rw-r--r-- 1 root     root        3 Jun 24 08:09 docker.pid
srw-rw---- 1 root     docker      0 Jun 24 08:09 docker.sock
-rw-r--r-- 1 root     root        4 Jun 24 08:09 docker-ssd.pid
drwxr-xr-x 3 root     root     4096 Jun 20 22:34 google
drwxrwxrwt 2 root     root     4096 Jan  1  1970 lock
drwxr-xr-x 2 root     root     4096 Jun 24 08:09 metrics
drwxr-xr-x 2 root     root     4096 Jan  1  1970 mount
drwxrwsr-x 2 postgres postgres 4096 Jun 20 21:54 postgresql
-rw-r--r-- 1 root     root        1 Jun 24 08:09 rsyslogd.pid
drwxr-xr-x 3 root     root     4096 Jun 20 21:52 runit
drwxr-xr-x 2 root     root     4096 Jun 20 21:55 sshd
-rw-r--r-- 1 root     root        4 Jun 24 08:09 sshd.pid
-rw-r--r-- 1 root     root        3 Jun 24 08:09 supervisor.pid
-rw-rw-r-- 1 root     utmp      768 Jun 24 08:09 utmp
-rw------- 1 root     root        0 Jun 24 08:09 xtables.lock

常见文件操作

API 语义
open 打开或创建一个文件
read 从一个已打开的文件中读取数据
write 向一个已打开的文件中写入数据
close 关闭一个已经打开的文件句柄

开发者可以直接调用 API 对文件进行操作,而无需关心文件的具体类型,这种 “多态性” 是直接建立在操作系统上面的。

小结

Linux 中 一切皆为文件 的设计理念带来了许多好处:

  • 统一接口: 使用相同的 API 可以对所有类型的文件进行操作,例如读取、写入、移动、删除、修改权限等
  • 简化管理: 使用相同的工具和方式来管理文件和设备的操作,例如备份、复制、移动、删除、链接等
  • 编程性 : 一个程序可以通过文件与其他程序通信,使得程序之间的交互、测试、集成等行为变得更容易,并且可以针对不同的应用场景,使用适用的编程语言来编写代码,提升灵活性和开发效率
  • 扩展性 : 可以创建自定义的文件系统以支持特定的文件或设备类型,最终将新的硬件或软件集成到已有系统中

Reference