4124 个字词
21 分钟
Linux 学习笔记 3 —— 核心命令与系统管理
首次发布: 2026-04-01
... 次访问

Linux系统的一个核心设计哲学是”一切皆文件”,这一理念在设备管理上体现得淋漓尽致。本章将带你深入了解Linux如何将硬件设备抽象为文件,以及如何与这些设备进行高效、安全的交互。

3.1 设备文件#

Linux内核将硬件设备抽象为特殊的文件,这些文件通常位于/dev目录下,被称为设备节点设备文件。这种设计使得用户空间程序可以通过标准的文件操作(如open()read()write()close())来与硬件设备进行交互,大大简化了设备编程的复杂性。

3.1.1 设备文件类型#

当你使用ls -l命令查看/dev目录时,会发现文件名前的第一个字符标识了设备的类型:

ls -l /dev | head -20

常见的设备文件类型包括:

  • b - 块设备 (Block device):以固定大小的数据块(通常是512字节或4KB)进行读写,支持随机访问。硬盘、SSD、USB存储设备都属于块设备。例如/dev/sda/dev/nvme0n1

  • c - 字符设备 (Character device):处理字符流,通常不支持随机访问,数据按顺序读写。键盘、鼠标、串口、终端都属于字符设备。例如/dev/tty1/dev/input/mouse0

  • p - 管道设备 (Pipe device):用于进程间通信(IPC),数据单向流动。

  • s - 套接字设备 (Socket device):用于网络通信或特定进程间通信。

3.1.2 主次设备号#

ls -l的输出中,除了文件类型标识符,第5列和第6列的数字分别代表主设备号(Major number)和次设备号(Minor number):

ls -l /dev/sda
# brw-rw---- 1 root disk 8, 0 Jan 15 10:30 /dev/sda
#                        ↑  ↑
#                      主设备号 次设备号
  • 主设备号:标识设备对应的驱动程序。相同类型的设备通常共享同一个主设备号。例如,所有SCSI磁盘的主设备号都是8。

  • 次设备号:标识具体的设备实例。例如,/dev/sda的次设备号是0,/dev/sdb的次设备号是16。

除了ls -l,你还可以直接查看sysfs中的设备号文件:

cat /sys/block/sda/dev
# 输出: 8:0

3.1.3 并非所有设备都有文件#

值得注意的是,并非所有硬件设备都有对应的/dev文件。例如,网络接口通常没有设备文件,而是通过套接字(sockets)API与内核交互。这种设计反映了不同设备的访问模式差异。

3.2 sysfs 设备路径#

虽然/dev目录提供了一种简单直观的设备访问方式,但设备名(如/dev/sda)可能在系统重启或硬件配置改变后发生变化。为了提供一个基于硬件属性的、稳定的设备视图,Linux内核引入了sysfs文件系统。

3.2.1 sysfs 的作用#

sysfs是一个虚拟文件系统,通常挂载在/sys目录下。它将内核中的设备、驱动、总线等对象以文件和目录的形式暴露给用户空间,形成了一个层次化的设备树。

sysfs中的文件和目录主要供程序读取,虽然某些文件可以写入(用于配置设备),但不要随意手动修改,除非你完全清楚自己在做什么。错误的修改可能导致系统不稳定。

3.2.2 sysfs 路径结构#

sysfs的路径详细描述了设备的物理连接关系。例如,一个SATA硬盘/dev/sdasysfs中的完整路径可能是:

/sys/devices/pci0000:00/0000:00:17.0/ata3/host0/target0:0:0/0:0:0:0/block/sda

这个路径告诉我们:

  • 设备连接在PCI总线的0000:00:17.0控制器上
  • 通过ATA协议连接
  • 是第3个ATA主机上的第1个目标设备
  • 最终在block子系统下表现为sda

3.2.3 使用 udevadm 查询设备信息#

当在/dev中难以找到设备的sysfs位置时,udevadm命令是一个强大的工具:

# 查看设备的所有属性
udevadm info --query=all --name=/dev/sda

# 查看设备的sysfs路径
udevadm info --query=path --name=/dev/sda

# 以树状结构显示设备属性
udevadm info --attribute-walk --name=/dev/sda

3.3 dd 命令与设备#

dd(data duplicator)是一个功能强大的命令行工具,用于在文件和设备之间复制数据。它在处理块设备和字符设备时特别有用。

3.3.1 基本语法#

dd if=input_file of=output_file [options]

3.3.2 常用选项#

  • if:指定输入文件(默认为标准输入)
  • of:指定输出文件(默认为标准输出)
  • bs:指定读写块的大小(例如bs=1024bs=1M
  • count:指定要复制的块的总数
  • skip:在复制前跳过输入文件的指定块数
  • seek:在写入前跳过输出文件的指定块数

3.3.3 实用示例#

dd命令非常强大,但也非常危险。错误的参数可能导致数据永久丢失。在执行任何dd命令前,请务必仔细检查ifof参数,确保它们指向正确的设备。

创建空白文件:

# 创建一个100MB的空白文件
dd if=/dev/zero of=testfile bs=1M count=100

备份MBR(主引导记录):

# 备份第一块磁盘的前512字节(MBR)
dd if=/dev/sda of=mbr_backup.img bs=512 count=1

# 恢复MBR
dd if=mbr_backup.img of=/dev/sda bs=512 count=1

创建可启动USB:

# 将ISO镜像写入USB设备(假设USB设备是/dev/sdb)
dd if=ubuntu.iso of=/dev/sdb bs=4M status=progress

测试磁盘读写速度:

# 测试写入速度
dd if=/dev/zero of=testfile bs=1G count=1 oflag=direct

# 测试读取速度
dd if=testfile of=/dev/null bs=1G iflag=direct

3.4 常见设备命名汇总#

在Linux系统中,不同类型的设备遵循不同的命名规则。了解这些规则对于系统管理和故障排查至关重要。

3.4.1 硬盘:/dev/sd*#

现代Linux系统中的大多数硬盘(包括SATA、SCSI、USB存储)都使用sd前缀(SCSI Disk)。

命名规则:

  • /dev/sda:第一块磁盘
  • /dev/sdb:第二块磁盘
  • 分区命名:/dev/sda1/dev/sda2

设备名变动问题:

设备名的分配顺序取决于内核加载驱动的顺序。如果硬件配置改变(如拔掉一个USB设备),设备名可能会发生变化,导致/etc/fstab挂载失败。

3.4.2 虚拟磁盘:/dev/xvd*, /dev/vd*#

在虚拟机环境中,磁盘设备通常使用不同的命名约定:

  • Xen虚拟化/dev/xvda, /dev/xvdb
  • KVM/QEMU/dev/vda, /dev/vdb
  • AWS EC2/dev/xvda, /dev/xvdb

3.4.3 非易失性内存:/dev/nvme*#

NVMe(Non-Volatile Memory Express)是一种高性能的存储协议,专为SSD设计。

命名规则:

  • /dev/nvme0n1:第一个NVMe控制器上的第一个命名空间
  • /dev/nvme0n1p1:第一个NVMe控制器上第一个命名空间的第一个分区
# 查看NVMe设备信息
nvme list

3.4.4 设备映射器:/dev/dm-*, /dev/mapper/*#

设备映射器(Device Mapper)是Linux内核的一个框架,用于支持逻辑卷管理(LVM)、磁盘加密(LUKS)等高级功能。

命名规则:

  • /dev/dm-0, /dev/dm-1:内核分配的设备映射器设备
  • /dev/mapper/vg00-lv_root:LVM逻辑卷的符号链接
# 查看设备映射器设备
dmsetup ls

3.4.5 光驱:/dev/sr*, /dev/hd*#

光驱设备的命名取决于接口类型:

  • SCSI/SATA光驱/dev/sr0, /dev/sr1
  • 旧式PATA光驱/dev/hdc, /dev/hdd
# 挂载光盘
mount /dev/sr0 /mnt/cdrom

# 弹出光盘
eject /dev/sr0

3.4.6 终端:/dev/tty*, /dev/pts/*#

终端设备用于字符输入输出:

  • 虚拟控制台/dev/tty1, /dev/tty2等(通过ALT+F1-F6切换)
  • 伪终端/dev/pts/0, /dev/pts/1等(用于SSH、终端模拟器)
  • 当前终端/dev/tty
# 查看当前终端
tty
# 输出: /dev/pts/0

# 向其他终端发送消息
echo "Hello from $(whoami)" > /dev/pts/1

3.4.7 网络接口#

网络接口是Linux中一个特例,它们没有对应的/dev设备文件。这是因为网络数据包的传输不遵循简单的字节流模型,而是通过更复杂的套接字(sockets)API进行。

查看网络接口:

# 现代方法
ip link show

# 传统方法(可能需要安装net-tools)
ifconfig

接口命名:

  • 传统命名eth0(以太网)、wlan0(无线网)
  • 可预测网络接口名enp0s3(PCI总线上的以太网卡)、wlp2s0(PCI总线上的无线网卡)

3.5 设备名持久化#

由于内核按发现顺序分配设备名(如sda, sdb),硬件配置的微小变化都可能导致设备名错乱,进而破坏依赖于设备名的系统配置(如/etc/fstab)。为了解决这个问题,Linux提供了两种主要的持久化方案。

3.5.1 UUID 和 Label#

这是最常用的方法。每个文件系统在创建时都会被赋予一个UUID(全局唯一标识符)和一个可选的Label(标签)。无论设备在哪个端口,其UUID和Label都不会改变。

查找UUID和Label:

# 使用blkid命令(需要root权限)
sudo blkid /dev/sda1

# 输出示例: 
# /dev/sda1: UUID="a1b2c3d4-e5f6-7890-g1h2-i3j4k5l6m7n8" TYPE="ext4" LABEL="MyData"

在 /etc/fstab 中使用:

# 使用UUID挂载
UUID=a1b2c3d4-e5f6-7890-g1h2-i3j4k5l6m7n8 /mnt/data ext4 defaults 0 2

# 或者使用Label挂载
LABEL=MyData /mnt/data ext4 defaults 0 2

/etc/fstab中的每一行包含6个字段:

  1. 设备标识(UUID、LABEL或设备名)
  2. 挂载点
  3. 文件系统类型
  4. 挂载选项
  5. dump备份标志(0=不备份)
  6. fsck检查顺序(0=不检查)

3.5.2 udev 规则#

udev是Linux的设备管理器,它在内核检测到设备时动态地在/dev目录下创建和删除设备节点。你可以编写自定义的udev规则来为特定设备创建固定的符号链接。

规则文件位置: /etc/udev/rules.d/

规则文件命名: 通常以数字开头(如99-custom.rules),数字决定规则执行的优先级。

规则示例: 为一个特定序列号的USB硬盘创建固定链接/dev/my_usb_disk

# 首先,获取设备的唯一属性
udevadm info --attribute-walk --name=/dev/sdb

# 然后,在/etc/udev/rules.d/99-my-usb.rules中添加规则
SUBSYSTEM=="block", ATTRS{serial}=="ABC123456789", SYMLINK+="my_usb_disk"

重新插拔设备后,/dev/my_usb_disk就会指向该设备。

  1. 规则文件名必须以.rules结尾
  2. 规则中的属性值必须完全匹配(区分大小写)
  3. 修改规则后,需要重新加载udev规则:sudo udevadm control --reload-rules
  4. 测试规则:sudo udevadm test $(udevadm info -q path -n /dev/sdb)

3.6 内存设备#

Linux将内存也抽象为设备文件,位于/dev目录下。这些特殊的设备文件提供了对系统内存和随机数生成器的访问。

3.6.1 /dev/mem#

代表系统的主物理内存。直接读写此设备极其危险,通常只被内核调试工具使用。

直接读写/dev/mem可以访问任意物理内存地址,包括内核空间。错误的操作可能导致系统崩溃或安全漏洞。除非你是内核开发者或在进行底层调试,否则不要使用这个设备。

3.6.2 /dev/null#

一个特殊的”黑洞”设备。任何写入它的数据都会被丢弃,任何从它读取的操作都会立即返回EOF(文件结束)。

实用示例:

# 丢弃命令的标准输出
some_command > /dev/null

# 丢弃命令的错误输出
some_command 2> /dev/null

# 丢弃命令的所有输出
some_command &> /dev/null

# 作为空输入源
cat /dev/null > logfile  # 清空文件

3.6.3 /dev/zero#

一个无限的数据源,每次读取都会返回空字节(\0)。常用于创建指定大小的空白文件或作为数据流的输入。

实用示例:

# 创建一个100MB的空白文件
dd if=/dev/zero of=blank_file bs=1M count=100

# 作为压缩测试的输入源
dd if=/dev/zero bs=1M count=100 | gzip > test.gz

3.6.4 /dev/random 和 /dev/urandom#

提供加密安全的随机数。

  • /dev/random:真随机数生成器,基于环境噪声(如键盘敲击、鼠标移动)收集熵。当熵池耗尽时会阻塞,等待新的熵。
  • /dev/urandom:伪随机数生成器,使用密码学安全的算法生成随机数。永不阻塞,对于绝大多数应用(包括密钥生成)已足够安全。

实用示例:

# 生成一个32字节的随机密码(推荐使用urandom)
head -c 32 /dev/urandom | base64

# 生成SSH密钥
ssh-keygen -t ed25519 -f ~/.ssh/id_ed25519 -N "$(head -c 32 /dev/urandom | base64 | head -c 20)"

# 安全地擦除磁盘(使用随机数据覆盖)
dd if=/dev/urandom of=/dev/sdb bs=1M status=progress

对于现代Linux系统(内核版本≥4.8),/dev/urandom在系统启动后就已经有足够的熵,推荐优先使用/dev/urandom。只有在极少数对随机性要求极高的场景(如生成根CA证书)时,才考虑使用/dev/random

3.7 显示设备#

显示设备负责将图形输出到屏幕。Linux内核通过帧缓冲区(framebuffer)设备/dev/fb*提供对显存的原始访问,但用户空间的应用程序通常通过更高级的图形子系统(如X Window System, Wayland)与之交互。

查看帧缓冲设备:

ls /dev/fb*
# 通常只有一个 /dev/fb0

获取帧缓冲信息:

# 查看帧缓冲的详细信息
cat /sys/class/graphics/fb0/name
cat /sys/class/graphics/fb0/virtual_size

3.8 CPU 与设备#

CPU本身也被视为一种设备。/proc/cpuinfo文件提供了关于系统CPU的详细信息。

查看CPU信息:

# 查看完整的CPU信息
cat /proc/cpuinfo

# 只查看处理器型号
cat /proc/cpuinfo | grep "model name" | uniq

# 查看CPU核心数
nproc

# 查看CPU架构
uname -m

实用示例:

# 获取CPU核心数(用于并行任务)
CORES=$(nproc)
echo "系统有 $CORES 个CPU核心"

# 根据核心数设置make的并行编译
make -j$((CORES + 1))

/proc/cpuinfo中的每个processor块代表一个逻辑CPU核心。在超线程CPU上,物理核心数通常是逻辑核心数的一半。你可以通过cpu cores字段查看每个物理CPU的核心数。

3.9 监视设备活动#

了解设备当前的活动状态对于系统性能调优至关重要。Linux提供了多种工具来监视设备活动。

3.9.1 iostat#

iostat报告CPU使用率和I/O设备(主要是磁盘)的统计信息。

安装和使用:

# 安装sysstat包(如果未安装)
sudo apt install sysstat  # Debian/Ubuntu
sudo yum install sysstat  # RHEL/CentOS

# 每2秒报告一次磁盘I/O
iostat -x 2

# 只查看磁盘统计
iostat -d 2

# 查看特定设备
iostat -x /dev/sda 2

输出字段解释:

  • rrqm/s, wrqm/s:每秒合并的读/写请求数
  • r/s, w/s:每秒完成的读/写请求数
  • rkB/s, wkB/s:每秒读取/写入的千字节数
  • await:I/O请求的平均等待时间(毫秒)
  • %util:设备的利用率(接近100%表示设备饱和)

3.9.2 iotop#

iotop类似于top命令,但专门用于监视磁盘I/O。它可以显示哪些进程正在大量读写磁盘。

安装和使用:

# 安装iotop
sudo apt install iotop  # Debian/Ubuntu
sudo yum install iotop  # RHEL/CentOS

# 以root身份运行
sudo iotop

# 只显示有I/O活动的进程
sudo iotop -o

# 按I/O排序
sudo iotop -o -d 2

3.9.3 其他实用工具#

dstat: 一个全能的系统资源统计工具,可以同时监视CPU、内存、磁盘、网络等。

# 安装dstat
sudo apt install dstat

# 监视所有资源
dstat -tamdng 2

vmstat: 报告虚拟内存统计信息,包括进程、内存、分页、块I/O、陷阱和CPU活动。

# 每2秒报告一次
vmstat 2

# 只查看块设备活动
vmstat -D

3.10 实战演练#

理论知识需要通过实践来巩固。以下是一些实用的练习,帮助你更好地理解和掌握本章内容。

3.10.1 探索你的设备#

# 1. 列出所有块设备
lsblk

# 2. 查看详细的设备信息
sudo blkid

# 3. 探索sysfs中的设备树
ls -la /sys/block/

# 4. 查看特定设备的sysfs属性
cat /sys/block/sda/queue/scheduler
cat /sys/block/sda/device/model

3.10.2 创建和测试设备#

# 1. 创建一个100MB的测试文件
dd if=/dev/zero of=test.img bs=1M count=100

# 2. 将测试文件格式化为ext4文件系统
mkfs.ext4 test.img

# 3. 挂载测试文件
sudo mkdir /mnt/test
sudo mount -o loop test.img /mnt/test

# 4. 在挂载点创建一些文件
echo "Hello, World!" > /mnt/test/hello.txt
ls -l /mnt/test/

# 5. 卸载并清理
sudo umount /mnt/test
sudo rm -rf /mnt/test
rm test.img

3.10.3 监控磁盘I/O#

# 1. 在一个终端中运行iotop
sudo iotop -o

# 2. 在另一个终端中执行磁盘密集型操作
dd if=/dev/zero of=/tmp/largefile bs=1M count=1000

# 3. 观察iotop中的I/O活动
# 你应该能看到dd进程的I/O速率

# 4. 清理测试文件
rm /tmp/largefile

3.10.4 使用UUID挂载设备#

# 1. 查找设备的UUID
sudo blkid /dev/sdb1

# 2. 创建挂载点
sudo mkdir /mnt/data

# 3. 临时使用UUID挂载
sudo mount UUID="your-uuid-here" /mnt/data

# 4. 永久配置(需要root权限)
# 编辑 /etc/fstab,添加一行:
# UUID=your-uuid-here /mnt/data ext4 defaults 0 2

# 5. 测试fstab配置
sudo mount -a
  1. 在虚拟机或测试环境中练习,避免误操作影响生产系统
  2. 备份重要数据,特别是在使用dd命令时
  3. 仔细检查设备名,确保操作的是正确的设备
  4. 使用sudo时要格外小心,确认命令的每个参数
Linux 学习笔记 3 —— 核心命令与系统管理
https://adalovelemon.github.io/blog/posts/content/technotes/linux/linux3/
Author
Ada Lovelemon
Published at
2026-04-01

留言板