RHCSA 学习笔记

学习红帽课程中的一些笔记。

Linux系统基础快捷键

功能分类 快捷键 核心用途 / 考场高效技巧
光标快速定位 Ctrl + A 快速跳转至行首(无需长按左方向键)。
Ctrl + E 快速跳转至行尾
高效文本修正 Ctrl + U 剪切/删除从光标位置至行首的所有内容(输错复杂命令时快速清空)。
Ctrl + K 剪切/删除从光标位置至行尾的所有内容。
Ctrl + W 删除光标左侧的一个单词(修正参数极快)。
Alt + . 快速粘贴上一条命令的最后一个参数(如 vim /path/to/file 后接 cat / ls 时无需重新打路径)。
历史命令搜索 Ctrl + R 反向搜索历史命令,输入关键字快速复用长命令。
sudo !! (输入命令) 重新用 sudo 执行上一条因权限不足报错的命令。
进程与终端控制 Ctrl + C 强制中断当前前台运行的命令(如 Ping 或卡住的脚本)。
Ctrl + Z 挂起进程至后台(搭配 bg 后台运行或 fg 切回前台)。
Ctrl + L 快速清屏(保持当前已输入内容不丢失)。
Ctrl + D 退出/注销当前 Shell(相当于 exit,快速退出 SSH 或切换用户)。
补全与效率 Tab (按两次) 自动补全命令/路径/参数,按两次列出所有匹配项(考场拼写检查利器)。

文件系统结构和文件管理命令

文件结构

目录路径 英文名称 / 含义 核心作用与主要内容 常见文件 / 子目录示例
/ Root Directory 根目录。整个文件系统的起点,所有文件、目录和设备挂载点均由它延伸。
/bin
/usr/bin
User Binaries 基础用户命令。包含系统所有用户(普通用户和管理员)均可调用的基础二进制可执行命令(现代系统通常软链接至 /usr/bin)。 ls, cd, cp, mv, cat
/sbin
/usr/sbin
System Binaries 系统管理命令。包含超级管理员(root)用于系统维护、网络配置及关机等的高权限命令(现代系统通常软链接至 /usr/sbin)。 fdisk, ip, reboot, iptables
/etc Editable Text Configuration 核心系统配置文件。包含系统所有服务、应用程序、网络及全局环境的纯文本配置文件。 ansible.cfg, fstab, hosts, ssh/
/home User Home Directories 普通用户家目录。系统为每个普通用户创建的个人专属工作空间,存放用户的个人配置文件与文档。 /home/user1, /home/dev
/root Root Home Directory 超级管理员(root)家目录。独立于 /home 之外,确保即使 /home 挂载分区故障,root 用户仍能登录维护系统。 /root/.bashrc, /root/scripts/
/var Variable Data Files 动态变化数据。存放体积频繁增减或持续追加的文件,如系统日志、服务数据库、邮件队列和缓存。 /var/log/, /var/lib/docker/, /var/spool/
/usr User System Resources 用户系统资源。存放只读的应用软件和库文件(类似于 Windows 的 Program Files),大部分通过包管理器安装的程序均在此。 /usr/bin, /usr/lib, /usr/local
/boot Boot Loader Files 引导与启动文件。存放系统启动必需的核心文件,包括内核镜像(vmlinuz)、初始化 RAM 磁盘(initramfs)及 GRUB 引导器。 vmlinuz-*, initramfs-*.img, grub2/
/dev Device Files 设备文件。Linux 秉承“一切皆文件”原则,所有物理硬件与虚拟设备均在此体现为抽象文件。 /dev/sda (硬盘), /dev/null, /dev/zero
/proc Process Information 内存虚拟文件系统。不占用硬盘空间,将当前正在运行的进程状态与内核参数实时映射为文件。 /proc/cpuinfo, /proc/meminfo, /proc/sys/
/sys System 内存虚拟文件系统。与内核底层设备模型配合,导出硬件设备的层级结构与驱动控制接口。 /sys/block/, /sys/class/net/
/tmp Temporary Files 临时文件。供系统和软件在运行时存放临时数据,系统重启或定期脚本会自动清理该目录。 *.tmp, 运行时临时缓存
/opt Optional Application Software 可选第三方软件。用于手动安装独立的第三方大型软件套件(通常不依赖系统默认包管理器)。 /opt/google/, /opt/containerd/
/media Removable Media 可移动介质挂载点。系统自动挂载 U 盘、光驱、移动硬盘等便携设备时的默认路径。 /media/usb
/mnt Mount 临时挂载点。供系统管理员手动临时挂载其他磁盘分区、网络共享目录(NFS/CIFS)等。 /mnt/data, /mnt/nfs
/lib
/usr/lib
/lib64
/usr/lib64
Libraries 动态共享库。存放 /bin/sbin 中的命令运行所依赖的核心动态链接库(类似于 Windows 的 .dll 文件)。 libc.so.*, ld-linux.so

文件相关的管理命令

命令 核心功能 常用选项 / 参数 实用操作示例 深度解析与注意事项
mkdir 创建文件夹
(Make Directory)
-p:递归创建多级子目录
-v:显示创建过程的详细信息
mkdir -p project/src/bin 使用 -p 参数可以一次性创建尚不存在的多层嵌套目录,若目录已存在也不会报错。
rmdir 删除空文件夹
(Remove Directory)
-p:递归删除上一层空目录
--ignore-fail-on-non-empty:忽略非空报错
rmdir empty_dir 只能删除空目录。如果目录下存在任何文件或子目录,命令将报错拒绝执行(安全性保护)。
rm 删除文件或目录
(Remove)
-r / -R:递归删除(用于目录)
-f:强制删除,不提示确认
-i:删除前逐一询问确认
rm -rf project/ 危险系数高!使用 rm -rf 时需极其谨慎,文件一旦删除无法从回收站恢复;建议配合 -i 校验。
cp 拷贝文件或目录
(Copy)
-r / -R:递归复制整个目录
-a:归档模式(保留权限/时间戳/软链接等属性)
-v:显示复制过程
cp -a /etc/ansible ./ 复制文件夹时必须添加 -r-a 选项;使用 -a 参数在备份配置文件时能完全保留原文件的所有者与权限属性。
mv 移动或重命名文件/目录
(Move)
-n:不覆盖已存在的目标文件
-f:强行覆盖不提示
-i:覆盖前提示确认
mv old.txt new.txt
mv file.txt /tmp/
源路径与目标路径在同一目录下为“重命名”;在不同目录下为“移动”。跨文件系统移动文件时实质是“复制后删除”。
file 查看文件真实类型
(File Type)
-b:简略模式,不显示文件名
-i:输出标准的 MIME 类型字符串
file /usr/bin/ls
file image.png
Linux 不依赖文件后缀名判断类型。file 通过探测文件开头的“魔数”(Magic Number)来识破真实格式(如可执行文件、文本、压缩包等)。

用户和权限管理

graph LR
    %% 静态身份区域
    subgraph 静态身份 ["/etc/passwd | group"]
        B["主组/初始用户组"]
        C["附加组"]
    end

    %% 动态状态区域
    subgraph 动态状态 ["动态状态 (id 命令查看)"]
        subgraph E ["支持用户组 (groups)"]
            subgraph D ["有效用户组 (gid)"]
                F["决定新建文件的所属组"]
            end
            G["决定能访问哪些组的文件"]
        end
    end

    %% 核心纽带与初始化流向
    B -->|默认初始化| D
    C -->|默认初始化| E

    %% 外部命令动作
    H[["命令: newgrp 目标组"]] -.->|临时切换有效组<br>需为小组成员或输入组密码| D

    %% 样式定义
    style B fill:#f9f,stroke:#333,stroke-width:2px
    style C fill:#bbf,stroke:#333,stroke-width:2px
    style D fill:#f96,stroke:#333,stroke-width:1px
    style E fill:#6c6,stroke:#333,stroke-width:2px
    style H fill:#fff,stroke:#333,stroke-width:2px

用户信息配置

密码文件 /etc/passwd

/etc/passwd 记录 Linux 系统上所有用户账号的基本属性信息(用户名、UID、GID、家目录、默认 Shell 等)。

1
2
3
4
5
6
7
8
root:x:0:0:root:/root:/bin/bash
│ │ │ │ │ │ └─ 7. 登录 Shell (Login Shell)
│ │ │ │ │ └─────── 6. 家目录 (Home Directory)
│ │ │ │ └───────────── 5. 备注信息 (GECOS / Comment)
│ │ │ └──────────────── 4. 主组 ID (GID)
│ │ └────────────────── 3. 用户 ID (UID)
│ └──────────────────── 2. 密码占位符 (Password)
└──────────────────────── 1. 登录名 (Username)

暗码文件 /etc/shadow

/etc/shadow 用于存储用户账号的哈希加密密码(Password Hash)以及密码有效期、到期警告等安全策略。

1
2
3
4
5
6
7
8
9
10
root:$6$xyz...123:19720:0:99999:7:14:20088:
│ │ │ │ │ │ │ │ └─ 9. 保留字段 (Reserved)
│ │ │ │ │ │ │ └────── 8. 账号失效日期 (Expiration Date)
│ │ │ │ │ │ └───────── 7. 宽限天数 (Inactive Days)
│ │ │ │ │ └─────────── 6. 到期警告天数 (Warning Days)
│ │ │ │ └───────────────── 5. 密码最大有效天数 (Max Days)
│ │ │ └─────────────────── 4. 密码最小修改间隔天数 (Min Days)
│ │ └───────────────────────── 3. 上次修改密码日期 (Last Change)
│ └────────────────────────────────────── 2. 加密密码 (Encrypted Password)
└────────────────────────────────────────── 1. 登录名 (Username)
字段序号 字段名称 计数基准 / 换算公式 详细解读与应用场景
3 上次修改密码日期
(Last Change)
Unix 纪元天数
1970-01-01 为第 0 天开始累加。

换算公式:
目标日期 = 1970-01-01 + 天数
示例(以 19720 为例):
从 1970年1月1日 往后加 19720 天,对应日期为 2024 年 1 月 3 日(表示该账号上次修改密码是在这一天)。

特殊值:
0:表示用户下次登录时必须立即修改密码(常用于管理员为新用户初始化密码)。
4 密码最小修改间隔天数
(Min Days)
相对天数
修改密码后必须等待的天数。
示例(以 0 为例):
表示无限制,用户可以在一天内随时修改多次密码。

安全作用(若设为 7):
用户修改密码后,最快必须等 7 天后才能再次修改。这可以防止用户为了绕过“历史密码不能重复”策略而连续快速修改密码。
5 密码最大有效天数
(Max Days)
相对天数
密码保持有效的最长期限。
示例(以 99999 为例):
99999 天约等于 273 年,相当于密码永不过期(系统默认值)。

合规场景(若设为 90):
配合字段 3 算出的日期,密码将在上次修改后的第 90 天强制过期,系统会要求必须更换密码。
6 到期警告天数
(Warning Days)
倒计时天数
密码过期前的提醒窗口。
示例(以 7 为例):
在密码即将过期的前 7 天内,用户每次通过 SSH 或终端登录时,系统都会输出警告消息:Warning: your password will expire in X days. 提醒提前更换。
7 宽限天数
(Inactive Days)
相对天数
密码过期后的“缓冲期”。
示例(若设为 14):
如果密码过期后用户一直没改,在过期后的 14 天内登录,系统仍允许其登录并修改密码;若超过 14 天依然未修改,账号将进入 Inactive(失效锁定) 状态,此时用户自行改密码也无效,必须由 root 解锁。

留空(默认):
表示无宽限期,一旦密码过期立即无法登录。
8 账号失效日期
(Expiration Date)
Unix 纪元天数
1970-01-01 为第 0 天开始累加。
绝对截止时间(与密码是否过期无关):
主要用于外包人员、临时工或有明确离职/到期日期的账号。

示例(若设为 20088):
对应日期为 2025 年 1月 6 日。到了这一天,无论密码是否刚刚修改过,该账号彻底禁止登录。

留空(默认):
表示账号永久有效。

Gemini 拓展
你可能会觉得既然 /etc/passwd 里现在根本没有密码(都移到 shadow 里去了),官方为什么还叫它 Password file?
这其实是一个历史包袱。在 20 世纪 70、80 年代 Unix 刚诞生时,密码的加密串确实是直接写在这个文件里的。后来为了安全才剥离出了 shadow 机制。
但因为无数的底层 C 语言标准库函数(比如 getpwnam,全称就是 get pwassword name)和历史命令都绑定了这个名字,所以官方一直沿用了 Password file 这个古老的叫法,而在技术上通过引入 Shadow password file 来打补丁。

用户管理命令

命令 核心功能 常用选项 / 参数 实用操作示例 深度解析与注意事项
id 查看用户 ID 及组归属 (无参数):查看当前用户
username:查看指定用户
-u:仅输出 UID
-g:仅输出主组 GID
-G:输出所有所属组 GID
id
id devuser
用于快速核验用户的身份标识,输出包含:UID(用户ID)、GID(主组ID)以及 groups(所有附加组列表)。
useradd 创建新用户
(或 adduser)
-u:指定 UID
-g:指定初始主组(组名或 GID)
-G:指定附加组(多个用逗号隔开)
-d:指定家目录路径
-s:指定默认 Shell
useradd -s /sbin/nologin -G docker appuser 创建用户时,系统会默认参考 /etc/default/useradd/etc/skel/ 模板文件夹。指定 -s /sbin/nologin 可创建不可登录的服务账号。
userdel 删除用户 -r递归删除家目录及邮件池
-f:强制删除(即使该用户当前已登录)
userdel -r olduser 非常重要: 不加 -r 参数只会从 /etc/passwd 中移除账号记录,其家目录(/home/username)仍会残留在磁盘上变成“无主文件”。
usermod 修改已有用户信息 -aG追加附加组(必须配合 -a,否则会覆盖原有附加组)
-l:修改登录用户名
-s:修改默认 Shell
-L / -U:锁定 / 解锁账号
usermod -aG wheel devuser
usermod -s /bin/bash devuser
运维最常用 usermod -aG 给用户添加提权组(如 wheelsudo)。切记:如果不加 -a 只写 -G,会导致该用户从之前的所有附加组中被移除!
passwd 修改用户密码 (无参数):修改当前登录用户的密码
username:修改指定用户的密码(仅 root 可用)
-l / -u:锁定 / 解锁用户密码
-d:删除用户密码(清空后可免密登录)
--stdin:从标准输入读取密码(脚本批量设置密码神技)
passwd
echo "Password123" | passwd --stdin devuser
普通用户修改自己密码需要遵循复杂性校验规则;root 管理员可以强行修改任意用户的密码且无需校验旧密码。
chage 修改用户密码时效策略
(Change Age)
-l查看用户的密码到期与时效详细报告
-M:设置密码最大有效天数
-m:设置密码最小修改间隔天数
-W:设置到期警告天数
-d 0:强制用户下一次登录时必须修改密码
chage -l devuser
chage -M 90 -W 7 devuser
chage -d 0 devuser
直接操作 /etc/shadow 中关于天数限制的第 3 至第 8 字段。RHCE 考试中常用于配置企业级安全合规策略(如强制 90 天换密码、首次登录改密码等)。

组信息配置

用户组文件 /etc/group

/etc/group 记录了系统上所有用户组的基本属性,包括组名称、组 ID(GID)以及该组包含哪些成员用户。该文件对所有用户全局可读(权限 644),以便系统和程序能够将数字 GID 映射为可读的组名。

1
2
3
4
5
wheel:x:10:root,devuser
│ │ │ └─ 4. 附加组成员列表 (Group Members) 主组用户不会显示
│ │ └──── 3. 组 ID (GID)
│ └────── 2. 组密码占位符 (Group Password)
└────────── 1. 组名 (Group Name)

暗码组文件 /etc/gshadow

/etc/gshadow/etc/group 的安全补充文件,存储了用户组的加密密码以及组管理员(Group Administrators)信息。为了防止未授权用户破译密码,该文件具有极高权限限制(仅 root 可读写,权限通常为 000 或 400)。

1
2
3
4
5
wheel:$6$abc...789:root:devuser,testuser
│ │ │ └─ 4. 附加组成员列表 (Group Members)
│ │ └────── 3. 组管理员列表 (Group Administrators)
│ └─────────────────── 2. 加密组密码 (Encrypted Group Password)
└─────────────────────── 1. 组名 (Group Name)

用户组相关管理命令

命令 核心功能 常用选项 / 参数 实用操作示例 深度解析与注意事项
groupadd 创建新用户组 -g:指定组 ID (GID)
-r:创建系统用户组(GID 小于 1000)
groupadd -g 2000 devgroup
groupadd -r sysadmin
创建组时,系统会自动在 /etc/group/etc/gshadow 中同步添加条目。指定 -r 参数可用于创建系统服务专用的组。
groupmod 修改已有用户组属性 -n:修改组名
-g:修改组 ID (GID)
groupmod -n newgroup oldgroup
groupmod -g 2005 devgroup
修改 GID 后,原本属于该组的文件在磁盘上的 GID 不会自动变更,会导致那些文件显示为“无主 GID”(需要手动使用 chgrpfind 进行修复)。
groupdel 删除用户组 (无特殊常用选项) groupdel devgroup 非常重要: 不能删除任何现有用户的初始主组(Primary Group)。如果某组仍是某个用户的初始主组,必须先修改该用户的初始主组或删除该用户后,才能删除该组。
groupmems 管理指定组的成员
(需 root 或组管理员权限)
-g:指定要操作的目标组
-a:添加用户到组
-d:从组中删除用户
-l:列出该组的所有成员
-p:清空该组所有成员
groupmems -g devgroup -a user1
groupmems -g devgroup -l
usermod 更专注于“以组为中心”的成员管理,操作时直接修改 /etc/group/etc/gshadow 中的成员列表。
gpasswd 管理组密码、成员及组管理员 -a:添加用户到组
-d:从组中移除用户
-A:指定组管理员
-r:删除组密码
-M:批量设置组成员(覆盖式)
gpasswd -a user1 devgroup
gpasswd -d user1 devgroup
gpasswd -A manager1 devgroup
功能极强:不仅可以像 usermod 一样添加/删除成员,还能设置组密码(保存在 /etc/gshadow),以及指定组管理员(让普通用户无需 root 权限即可管理该组成员)。

文件权限

文件权限的表达方式

符号表达 八进制数值 对应权限含义 (对文件) 对应权限含义 (对目录)
r-- 4 仅允许读取文件内容 (cat, less) 仅允许查看目录内的文件名列表 (ls)
-w- 2 仅允许修改文件内容 (vim, >) 仅允许在目录内创建、删除、重命名文件
--x 1 仅允许将文件作为程序/脚本执行 仅允许进入该目录 (cd) 或访问内部文件
--- 0 无任何权限 无任何权限
s-- (SUID) 4 (前置位) 运行该文件时,执行者临时获得文件所有者的权限 (如 /usr/bin/passwd) 无实际特殊含义
-s- (SGID) 2 (前置位) 运行该文件时,执行者临时获得文件所属组的权限 目录下新建的文件/子目录会自动继承该目录的所属组(常用于协同共享目录)
--t (Sticky) 1 (前置位) 无实际通用含义(早期用于缓存程序在内存中) 目录对所有人开放写权限,但仅文件创建者和 root 才能删除或修改内部文件 (如 /tmp)
1
2
3
4
5
- rwx r-x r--
│ │ │ └─ [3] 其他人权限 (Others): r-- = 4+0+0 = 4 (只读)
│ │ └───── [2] 所属组权限 (Group) : r-x = 4+0+1 = 5 (读+执行)
│ └───────── [1] 所有者权限 (User) : rwx = 4+2+1 = 7 (读+写+执行)
└──────────── [0] 文件类型 : - (普通文件) / d (目录) / l (软链接)

文件权限的查看以及修改

命令 核心功能 常用选项 / 参数 实用操作示例 深度解析与注意事项
ls -l 查看文件权限及详细属性 -a:显示所有文件(包含 . 开头的隐藏文件)
-d:仅显示目录本身的属性,而非目录内的文件内容
-h:以人类可读的格式显示文件大小(如 K、M、G)
-Z:显示文件的 SELinux 安全上下文(RHCE 必考)
ls -la
ls -ldh /var/log
ls -lZ /var/www/html
第一列共 10 位字符(如 -rwxr-xr--),第 1 位表示文件类型,后 9 位每 3 位一组,分别代表所有者 (u)、所属组 (g) 和其他人 (o) 的基础权限与特殊权限。
chmod 修改文件或目录的访问权限
(Change Mode)
-R递归修改目录及其内部所有文件和子目录的权限
u/g/o/a:指定操作对象(所有者/所属组/其他人/全部)
+/-/=:指定权限变更动作(增加/移除/精准赋值)
• 4 位八进制数:设置包含特殊权限在内的绝对数字权限
chmod 755 script.sh
chmod -R 770 /project
chmod u+x,g-w file.txt
chmod 2770 /shared_dir
支持八进制数字法(如 755)和符号表示法(如 u+x)。使用四位八进制数时,千位代表特殊权限:SUID (4)、SGID (2)、Sticky Bit (1)。给协同目录设置 SGID(如 chmod 2770)是 RHCE 考试的高频考点。
chown 修改文件或目录的所有者和所属组
(Change Owner)
-R递归修改目录及其内部所有文件的所有者与所属组
--reference=ref_file:参照指定文件的属主与属组进行修改
chown devuser file.txt
chown devuser:devgroup /app
chown -R nginx:nginx /var/www/html
仅 root 管理员可执行。使用 用户:组 语法可以一次性同时修改所有者和所属组;如果只写 chown :groupname file,效果等同于 chgrp;若写 chown user: file,则会把所属组自动同步修改为该用户的初始主组。
chgrp 仅修改文件或目录的所属组
(Change Group)
-R递归修改目录及其内部所有文件的所属组
--reference=ref_file:参照指定文件的属组进行修改
chgrp devgroup file.txt
chgrp -R docker /var/lib/docker
专注于修改组归属的命令。普通用户只有在既是该文件的所有者,同时又是目标组的成员时,才能使用此命令将文件改给自己所在的另一个组;root 则无此限制。现代运维中更多倾向直接使用 chown :groupname 代替。

IO重定向和管道符

重定向

  • 标准 I/O 数据流与 IO 目标
描述符 / 标识 类型 标准文件描述符 (FD) 核心功能与默认流向
stdin 标准输入
(Standard Input)
0 接收程序的数据输入,默认来源于键盘或前置命令的管道输出。
stdout 标准输出
(Standard Output)
1 输出程序的正常执行结果,默认直接打印到终端屏幕。
stderr 标准错误
(Standard Error)
2 输出程序运行时的错误或警告信息,默认独立打印到终端屏幕(不受 1> 重定向影响)。
filename 磁盘文件路径 存储数据的物理或虚拟文件,通常作为重定向的目标(如 > filename)或命令处理的对象。

输出重定向

重定向符号
重定向符号 完整/等价语法 操作模式 目标流 (FD) 核心功能与运行机制 实用操作示例
> 1> 覆盖 (Overwrite) 标准输出 (stdout / 1) 将命令的正常输出清空写入到指定文件;若文件不存在则自动创建,若已存在则直接冲掉原有内容。 date > time.txt
ls -l 1> list.txt
>> 1>> 追加 (Append) 标准输出 (stdout / 1) 将命令的正常输出追加到指定文件的末尾;保留原内容,在文件尾部拼接新数据。 echo "new line" >> log.txt
2> 2> 覆盖 (Overwrite) 标准错误 (stderr / 2) 仅将命令产生的错误/警告信息清空写入到指定文件;正常输出依然直接打印到终端屏幕。 find / -name "*.conf" 2> err.log
2>> 2>> 追加 (Append) 标准错误 (stderr / 2) 仅将命令产生的错误/警告信息追加到指定文件的末尾;保留文件原有历史错误日志。 systemctl status nginx 2>> err_history.log
&> > file 2>&1 覆盖 (Overwrite) 全部输出 (1 + 2) 正常输出和错误信息混合合并后,清空写入到同一个文件中(RHCE/Bash 自动化脚本绝密常用)。 tar -czvf backup.tar.gz /data &> backup.log
&>> >> file 2>&1 追加 (Append) 全部输出 (1 + 2) 正常输出和错误信息混合合并后,一同追加到同一个文件的末尾。 cron_job.sh &>> /var/log/cron_all.log
拓展:特殊设备
特性 / 维度 /dev/null (空设备 / 黑洞) /dev/zero (零设备 / 数据源)
设备类型 字符设备 (Character Device) 字符设备 (Character Device)
写入行为 (Write) 接收并丢弃所有写入的数据,类似于“垃圾桶”或“数据黑洞”。 接收并丢弃所有写入的数据(与 /dev/null 相同)。
读取行为 (Read) 不提供任何数据,读取时立即返回 EOF (文件结束符) 持续输出无限的 null 字节 (ASCII 0x00 / \0)
核心应用场景 屏蔽不需要的命令输出、清空文件内容。 创建固定大小的空文件、初始化磁盘/Swap 分区、性能压测。
用法示例 不输出错误内容:
find /etc -name "*.conf" 2> /dev/null
(在系统中查找文件,将权限不足的路径信息丢弃,仅在屏幕上显示正常找到的路径)
创建指定大小的空文件 (如 1GB 的 Swap 交换文件):
dd if=/dev/zero of=/swapfile bs=1M count=1024
(从零设备提取数据生成 1GB 大小的填充文件)

管道符

管道符 | 用于将前一个命令的标准输出 (stdout / FD 1) 转换为后一个命令的标准输入 (stdin / FD 0)
通过管道,可以把多个单功能的小工具连接起来,实现复杂的数据处理流水线。

  • 语法格式:
1
command1 | command2 | command3 ...
  • 示例:
1
2
3
4
[root@lab opt]# echo abc | tr 'a-z' 'A-Z'           # 小写转大写
ABC
[root@lab opt]# ifconfig | grep inet6 | grep 64 # 匹配含有关键字的行
inet6 fe80::20c:29ff:fe15:890d prefixlen 64 scopeid 0x20<link>
  • 拓展:三通管道(tee 命令)
1
2
用法: command1 | tee command2 | command3
命令1的标准输出会分别传递到命令2和命令3
  • 示例:将 messages 的内容保存到 log1.txt,然后提取含 error 的行显示在屏幕
1
2
3
[root@lab opt]# cat /var/log/messages | tee log1.txt | grep -i "error"
Jul 19 10:39:25 lab kernel: unchecked MSR access error: RDMSR from 0x852 at rIP: 0xffffffffba87be02 (native_apic_msr_read+0x12/0x50)
...

vim 编辑器

工作模式切换

flowchart TD
    %% 模式节点定义
    Normal["<b>普通模式 (Normal Mode)</b><br><i>默认模式 / 导航与操作</i>"]
    Insert["<b>插入模式 (Insert Mode)</b><br><i>文本输入与修改</i>"]
    Visual["<b>视图模式 (Visual Mode)</b><br><i>文本选择与块操作</i>"]
    Command["<b>底行/命令行模式 (Command-line Mode)</b><br><i>保存、退出、查找与替换</i>"]

    %% 普通模式 -> 其他模式
    Normal -- "<kbd>i</kbd>/<kbd>a</kbd>/<kbd>o</kbd>/<kbd>I</kbd>/<kbd>A</kbd>/<kbd>O</kbd>" --> Insert
    Normal -- "<kbd>v</kbd>/<kbd>V</kbd>/<kbd>Ctrl</kbd>+<kbd>v</kbd>" --> Visual
    Normal -- "<kbd>:</kbd>/<kbd>/</kbd>/<kbd>?</kbd>" --> Command

    %% 其他模式 -> 返回普通模式
    Insert -- "<kbd>Esc</kbd>" --> Normal
    Visual -- "<kbd>Esc</kbd>" --> Normal
    Command -- "<kbd>Esc</kbd>/<kbd>Enter</kbd> (执行后)" --> Normal

    %% 样式美化
    style Normal fill:#2b5c8f,stroke:#4a90e2,stroke-width:2px,color:#fff
    style Insert fill:#2d7d46,stroke:#5cd685,stroke-width:2px,color:#fff
    style Visual fill:#b8621b,stroke:#f39c12,stroke-width:2px,color:#fff
    style Command fill:#6c3483,stroke:#bb8fce,stroke-width:2px,color:#fff
目标模式 从命令模式进入的触发按键 核心功能区别
插入模式 i / a:在光标 / 插入
I / A:在当前行行首 / 行尾插入br>• o / O:在当前行下方 / 上方新建行并插入
直接键入文本数据。
视图模式 v:字符选择模式
V:行选择模式
Ctrl + v:列/块选择模式(做批量注释、列编辑极度实用)
高亮选中指定文本,后续可配合 y(复制)、d(删除)、c(修改)等命令。
底行模式 ::执行保存 (:w)、退出 (:q)、替换 (:%s) 等全局指令
/:向下查找文本
?:向上查找文本
(查找模式中用 n / N 在多个关键字之间进行跳转)
在编辑器底部命令行输入拓展指令或正则表达式。

普通模式

分类 快捷键 核心功能与操作机制
光标移动 h / j / k / l 分别对应: / / / 移动一个字符。
w / b 向后(右)/ 向前(左)移动到下一个单词的词首。
0 / ^ / $ 0 移至行首;^ 移至行首第一个非空字符;$ 移至行尾。
gg / G gg 快速跳转到文件第一行G 跳转到文件最后一行
行号 G:行号 跳转到指定的行(例如 15G 跳转到第 15 行)。
Ctrl + f / Ctrl + b 向下(Forward)/ 向上(Backward)翻动一整屏。
文本编辑与删除 x 删除光标所在的当前字符(相当于 Delete)。
dd 删除(剪切)光标所在的整行。支持前缀数字,如 3dd 一次性删除 3 行。
dw / D dw 删除光标所在处至词尾;D 删除光标所在处至当前行尾。
cc / cw 删除整行 / 单词并立即切换至插入模式(Change 操作)。
复制与粘贴 yy 复制光标所在的整行。支持前缀数字,如 5yy 复制 5 行。
yw / y$ yw 复制光标所在处至词尾;y$ 复制光标所在处至行尾。
p / P p 粘贴到光标位置之后/下方P 粘贴到光标位置之前/上方
撤销与重做 u 撤销上一次的操作(Undo)。
Ctrl + r 重做撤销掉的操作(Redo)。
. 重复执行上一次的编辑操作(极为实用的重做点命令)。
模式切换 i / a / o 切换至插入模式:i 光标前;a 光标后;o 当前行下方新建行。
v / V / Ctrl + v 切换至视图模式:v 字符选择;V 行选择;Ctrl + v 块/列选择。
: / / : 进入底行命令模式;/ 进入向下查找模式。

插入模式

快捷键 功能分类 功能说明
Ctrl + u 快速删除 清空当前光标至行首的所有内容
Ctrl + w 快速删除 向前删除一个单词
Ctrl + h 快速删除 删除光标前的一个字符
Ctrl + a 文本复用 重复插入上一次插入模式录入的文本
Ctrl + e 文本参照 插入下一行同一列位置的字符
Ctrl + y 文本参照 插入上一行同一列位置的字符
Ctrl + o 模式切换 临时执行一条普通模式命令
Ctrl + n 自动补全 向下匹配补全单词/变量名
Ctrl + p 自动补全 向上匹配补全单词/变量名
Ctrl + x
Ctrl + f
自动补全 自动补全文件名或系统路径
Ctrl + t 格式调整 当前行增加缩进(向右移动)
Ctrl + d 格式调整 当前行减少缩进(向左移动)

命令行模式

分类 快捷指令 / 语法 核心功能与运行机制 实用操作示例
文件保存与退出 :w 保存(写入)当前文件到磁盘。 :w
:q 退出 Vim(若文件有未保存的修改则无法直接退出)。 :q
:wq:x / ZZ 保存修改并退出 Vim(ZZ 在普通模式直接按即可)。 :wq
:q! 强制退出,放弃所有未保存的修改。 :q!
:w filename 将当前内容另存为到指定的 filename 文件。 :w /tmp/backup.txt
行号控制 :set nu 显示行号 (number)。 :set nu
:set nonu 隐藏行号 (nonumber)。 :set nonu
:$ 快速跳转到最后一行的行首。 :$
查找与高亮 /pattern 从光标处向下/向后搜索字符串或正则表达式。 /error
?pattern 从光标处向上/向前搜索字符串或正则表达式。 ?warning
:noh:nohlsearch 取消高亮显示当前搜索选中的匹配结果。 :noh
文本替换 (:s) :[range]s/old/new/[flags] 在指定范围内进行文本查找与替换。 (见下方示例)
当前行替换 替换当前光标所在行的第一个匹配项。 :s/foo/bar/
当前行全局替换 替换当前光标所在行的所有匹配项 (g flag)。 :s/foo/bar/g
全文替换 替换整个文件(% 表示全文)中的所有匹配项。 :%s/foo/bar/g
带确认提示替换 替换全文并逐个交互询问确认 (c flag: confirm)。 :%s/foo/bar/gc
指定行范围替换 仅在指定行号范围内(如 10 到 20 行)进行替换。 :10,20s/foo/bar/g
外部系统交互 :!command 不退出 Vim 的情况下执行指定的 Bash 系统命令。 :!ls -l /etc
:r filename 读取并导入指定文件的内容,插入到当前光标所在行下方。 :r /etc/hosts
:r !command 将系统命令的标准输出直接插入到当前文件光标下方。 :r !date
多文件与环境配置 :e filename 在当前窗口直接打开并编辑另一个文件。 :e /etc/fstab
:set ignorecase 设置搜索时忽略大小写(简写 :set ic)。 :set ic
:set paste 开启粘贴模式,防止从外部复制带缩进的代码时样式混乱。 :set paste

可视化模式(仅作了解)

分类 快捷键 核心功能与操作机制 实用操作示例
进入模式 v 字符可视模式 (Visual Character Mode):按字符递进选择文本。 适合精准选中一小段文本或单个单词。
V 行可视模式 (Visual Line Mode):按整行递进选择文本。 适合快速选中多行代码或段落。
Ctrl + v 块可视模式 (Visual Block Mode):按矩形列/块选择文本。 常用于批量添加/删除注释。
范围调整 h / j / k / l 使用方向键或导航键扩展/缩减当前高亮选区。 配合 w$G 等快捷键可实现快速大范围选中。
o 切换选区光标端点:将光标在大高亮块的“起始端”和“结尾端”之间移动。 选中大段区域后,若想微调起始位置,无需取消重新选,按 o 即可切回起点调整。
选区操作 dx 剪切/删除:删除所有高亮选中的文本(并存入剪切板)。 选中指定多行或选区后直接按 d 即可清空。
y 复制:复制所有高亮选中的文本(拷贝到剪切板)。 选中后按 y,移动光标到目标位置按 p 粘贴。
c 修改:删除选中文本并直接进入插入模式 适合替换高亮选中的任意不规则区域。
> / < 缩进调整:将选中的整行文本向右缩进(>)或向左缩进(<)。 整理代码或脚本格式时,选中多行按 > 快速缩进。
u / U 大小写转换:将选区内的文本全部转为小写(u)或大写(U)。 批量修改变量或常量命名格式。
: 对选区执行底行指令:按 : 后,底部会自动出现 :'<,'> 前缀。 :'<,'>s/old/new/g
(仅在选中的文本范围内执行查找替换)

文本处理工具

文本查看工具

命令 核心特性与合并使用场景 常用快捷键与交互 实用操作示例
cat 小文件快速查看与多文件拼接
• 一次性将文件全部内容加载并输出到终端屏幕,适合内容简短的文件。
• 支持配合重定向符号(> / >>)高效合并或拼接多个文件。
优势:简单直接,方便管道传输与文件合并;不占用交互终端。
无交互(直接一次性输出)。 cat /etc/hosts
(查看小文件)
cat -n file.txt
(带行号显示)
cat a.txt b.txt > all.txt
(合并多文件)
more 中大型文件基础分页浏览
• 按页/按行加载并显示文本,解决大文件刷屏问题,适合一次性从头读到尾的场景。
优势:相比 cat 可控制阅读节奏;资源占用低,传统 UNIX 环境兼容性极佳。
Space:向下翻一页
Enter:向下翻一行
b:向上翻一页
q:退出查看
/string:向下查找
more /var/log/syslog
(基础分页查看日志)
ls -l /etc | more
(配合管道分页输出)
less 海量日志与超大文件高效交互检视(运维首选)
按需延迟加载:不论文件多大(如 10GB+)均可瞬间打开,极省内存。
• 支持完整 Vim 风格的前后自由滚屏、高亮搜索、跳转与实时监听。
优势:性能极强,检索体验极佳,不会卡死终端。
f / Space:向下翻页
b:向上翻页
g / G:跳至文件首 / 尾
/pattern:向下查找
?pattern:向上查找
n / N:跳转匹配项
F:实时监听追加(同 tail -f
less /var/log/messages
(高效检索海量日志)
less -N /etc/passwd
(带行号交互查看)
head 文件头部预览与格式校验
• 仅提取并显示文本开头的若干行(默认前 10 行)。
• 适合快速确认 CSV/日志的文件表头、配置开头或数据格式。
优势:执行极快,无需读取整个文件即可完成首部采样。
无交互。 head -n 5 /etc/passwd
(查看文件前 5 行)
head -c 100 file.txt
(查看文件前 100 字节)
tail 文件尾部查看与实时日志监控(排错神器)
• 默认显示文本最后 10 行;配合 -f / -F 参数可实现动态实时监听
• 运维排查服务报错、跟踪系统/应用实时写入日志的必备命令。
优势:精准定位最新数据,无需刷新即可实时抓取新增日志。
-f 实时监听状态下:Ctrl + c 退出监听。 tail -n 20 /var/log/nginx/error.log
(查看最后 20 行)
tail -f /var/log/nginx/access.log
(动态实时监听新增日志)

过滤行工具 grep

基于正则表达式从文本中快速匹配并过滤出特定内容。

  • grep 用法
分类 / 维度 命令参数 / 语法 核心功能与运行机制 实用操作示例
基础文本检索 grep "pattern" file 从指定文件中逐行匹配并打印包含模式(pattern)的行。 grep "root" /etc/passwd
大小写控制 -i 忽略大小写Ignore case),匹配时不区分大写和小写字母。 grep -i "error" /var/log/messages
显示匹配行号 -n 显示行号Line number),在输出的每一行前附加其在原文件中的行号。 grep -n "Failed password" /var/log/secure
统计匹配数量 -c 计数模式Count),不显示匹配的具体文本,仅输出匹配到的总行数。 grep -c "GET /index.html" /var/log/nginx/access.log
递归目录检索 -r / -R 递归目录Recursive),深入指定目录及其所有子目录下递归检索文件。 grep -rn "HOSTNAME" /etc/sysconfig/
匹配上下文关联 -A, -B, -C 打印匹配行的上下文文本:
-A n:同时打印匹配行之后After)的 n 行
-B n:同时打印匹配行之前Before)的 n 行
-C n:同时打印匹配行前后Context)各 n 行
grep -A 5 -B 2 "Exception" app.log
(输出报错行以及前 2 行和后 5 行的详细堆栈信息)
正则表达式拓展 -E (等价于 egrep) 扩展正则表达式Extended Regex),支持 ` (或)、+ (一次或多次)、?` (零次或一次) 等高级语法。
  • 搭配正则表达式
正则类型 语法 / 元字符 匹配逻辑与含义 实用 grep 命令示例 匹配结果/说明
位置锚定 ^ 匹配行首的位置。 grep "^root" /etc/passwd 匹配所有以 root 开头的行。
$ 匹配行尾的位置。 grep "bash$" /etc/passwd 匹配所有以 bash 结尾的行(查看默认 Shell 为 bash 的用户)。
^$ 匹配空白行(零字符行)。 grep -v "^$" /etc/sysctl.conf 匹配文件中的所有空行。
\<\b 匹配词首(单词左边界)。 grep "\<log" /var/log/messages 匹配以 log 开头的单词(如 loginlogout,但不匹配 blog)。
\>\b 匹配词尾(单词右边界)。 grep "log\>" /var/log/messages 匹配以 log 结尾的单词(如 blogsyslog,但不匹配 logging)。
字符匹配 . 匹配除换行符外的任意单个字符 grep "r..t" /etc/passwd 匹配 rootroatr12t 等字符序列。
[...] 匹配方括号内的任意单个字符 grep "[a-z]01" file.txt 匹配 a01b01 等(字母 + 01)。
[^...] 匹配不在方括号内的任意单个字符(取反)。 grep "[^0-9]123" file.txt 匹配非数字开头的 123(如 a123,不匹配 0123)。
基础重复
(BRE)
* 匹配前面的字符出现 0 次或多次 grep "go*d" file.txt 匹配 gdgodgoodgooood 等。
.* 匹配任意长度的任意字符(贪婪匹配)。 grep "Ip.*127" /etc/hosts 匹配行内包含 Ip 且后续有 127 的任意行。
\{n,m\} 匹配前面的字符出现 n 到 m 次 grep "a\{2,4\}" file.txt 匹配连续出现 2 到 4 次的字母 a(如 aaaaaaaaa)。
扩展重复
(ERE, 需 -E)
+ 匹配前面的字符出现 1 次或多次(至少 1 次)。 grep -E "go+d" file.txt 匹配 godgood(不匹配 gd)。
? 匹配前面的字符出现 0 次或 1 次(可选)。 grep -E "https?" urls.txt 同时匹配 httphttps
{n,m} 匹配前面的字符出现 n 到 m 次(无需转义)。 grep -E "a{2,4}" file.txt 同 BRE 逻辑,语法更简洁清晰。
逻辑与分组
(ERE, 需 -E)
| 逻辑或(Or),匹配分隔的多个模式之一。 grep -E "error|warning|fatal" app.log 同时匹配包含 errorwarningfatal 的行。
( ... ) 文本分组,把括号内的模式当作一个整体处理。 grep -E "(ip){2}" file.txt 匹配连续出现两次 ip 的单词(如 ipip)。
字符集合预定义
(POSIX 类)
[[:digit:]] 匹配任何阿拉伯数字(等价于 [0-9])。 grep "[[:digit:]]" file.txt 查找所有包含数字的行。
[[:alpha:]] 匹配任何大小写字母(等价于 [a-zA-Z])。 grep -E "^[[:alpha:]]+" file.txt 匹配以纯字母开头的行。
[[:alnum:]] 匹配字母和数字(等价于 [a-zA-Z0-9])。 grep -v "[[:alnum:]]" file.txt 匹配包含特殊符号或纯空格的行。
[[:space:]] 匹配任何空白字符(空格、Tab 制表符等)。 grep -E "[[:space:]]+$" file.txt 排错高频:检测并显示行尾带有残留多余空格/Tab的行。

文本截取工具 cut

按指定分隔符或字符位置切割并提取文本的特定列。

参数 / 维度 语法格式 核心功能与运行机制 实用操作示例
按分隔符提取列 -d "CHAR" -f N 最强高频用法-d 指定列分隔符(默认是 Tab 制表符),-f 指定提取第 N 列(多列用逗号隔开,范围用连字符 -)。 cut -d ":" -f 1,6 /etc/passwd
(提取 /etc/passwd 中的用户名第 1 列和家目录第 6 列)
提取指定列范围 -f N-M 连续提取第 N 列到第 M 列的内容;-f N- 表示从第 N 列到行尾;-f -M 表示从开头到第 M 列。 cut -d ":" -f 1-3 /etc/passwd
(提取第 1 到第 3 列)
cut -d ":" -f 3- /etc/passwd
(提取第 3 列及之后的所有列)
按字符位置提取 -c N-M 按固定字符数Characters)切割。提取每一行指定位置或范围的字符,不受分隔符影响。 cut -c 1-5 /etc/passwd
(提取每行前 5 个字符)
cut -c 1,3,5 file.txt
(仅提取第 1、3、5 个字符)
按字节位置提取 -b N-M 按字节数Bytes)切割。在纯 ASCII 文本中与 -c 效果相同,常配合 -n 参数避免打断多字节字符(如中文)。 cut -b 1-10 file.txt
(提取每行前 10 个字节)

文本分析工具 sort uniq wc

  • sort 排序工具
    对文本行按字母、数值或特定列进行排序。
选项 核心功能与运行机制 实用操作示例
-n 按数值大小Numeric)排序(默认按 ASCII/字符排序,如 10 会被排在 2 前面,加 -n 可正确识别数字)。 cat num.txt | sort -n
-r 逆序/降序Reverse)排列(从大到小或 Z-A)。 cat names.txt | sort -r
-k N 按指定列Key)排序。配合 -t 指定分隔符,可按特定列的内容进行排序。 sort -t ":" -k 3 -n /etc/passwd
(按 UID/第 3 列数值大小正序排列)
-u 排序并去重Unique)。在排序的同时删除重复行(效果等同于 sort | uniq)。 sort -u data.txt
-h 按人类可读单位Human-numeric)排序(正确识别 2K, 5M, 1G 等容量大小)。 du -sh * | sort -rh
(将当前目录下的文件/文件夹按占用空间降序排列)
  • uniq 去重工具
    去除或统计文本中连续相邻的重复行(常配合 sort 使用)。
选项 核心功能与运行机制 实用操作示例
(无参数) 相邻行去重关键前提uniq 只去除连续相邻的重复行,使用前必须先用 sort 排序! cat log.txt | sort | uniq
-c 统计重复次数Count)。在每一行前显示该行出现的总次数(运维频次统计核心参数)。 cat access.log | awk '{print $1}' | sort | uniq -c | sort -rn
(统计访问 IP 频次并按降序输出)
-d 仅显示重复行Repeated)。只输出在文件中出现两次或以上的行。 cat list.txt | sort | uniq -d
(找出所有重复的数据)
-u 仅显示唯一行Unique)。只输出在文件中仅出现过一次的行。 cat list.txt | sort | uniq -u
(过滤出完全无重复的数据)
-i 忽略大小写Ignore case)。去重比较时忽略字母大小写差异。 cat words.txt | sort | uniq -ic
  • wc 统计工具
    去除或统计文本中连续相邻的重复行(常配合 sort 使用)。
选项 核心功能与运行机制 实用操作示例
-l 统计总行数Lines)。统计文本的行数或管道传来的结果行数(高频使用)。 ls -1 /etc | wc -l
(统计 /etc 目录下的文件/子目录数量)
-w 统计单词数Words)。按空白字符分隔统计文本中的单词数量。 wc -w article.txt
-c 统计字节数Bytes)。统计文件或文本占用的字节总数。 wc -c file.txt
-m 统计字符数Chars)。统计文件中的字符总数(在 UTF-8 中文环境下与 -c 字节数不同)。 wc -m chinese.txt

文本对比工具 diff

  • diff 不建议直接使用,一般是简单判断文件是否被修改了
  • vimdiff 带有颜色高亮的比较工具,会进入到vim编辑器中

文本编辑工具 sed

sed(Stream Editor,流编辑器)是一种非交互式的文本处理工具。
它按行读取文本,并将数据放入临时缓冲区(模式空间)中,依据指定的规则进行文本匹配、替换、删除、插入或打印,处理完成后将结果输出到屏幕,默认不会直接修改原文件
sed 的核心优势在于高效的自动批处理和强大的正则替换,常用于 Shell 脚本中对配置文件的自动化修改与文本清洗。

graph TD
    Input["待处理的主文件 / 数据流"]
    PS["模式空间 (Pattern Space)<br>┌──────────────────────────┐<br>│  当前读入的单行文本工作台 │<br>└──────────────────────────┘"]
    
    OptionCheck{"是否使用了 -i 参数?<br>(In-place 原地修改)"}
    FileOut["写回 / 覆盖 原文件<br>(或生成 .bak 备份文件)"]
    Output["终端屏幕 / 输出管道<br>(标准输出 stdout)"]

    %% 1. 读取
    Input -->|"1. 逐行读取 (Read Line)"| PS
    
    %% 2. 内部处理 (自己指向自己)
    PS -->|"2. 执行 sed 指令 (如 s/a/b/g, d, p)<br>直接在内存工作台上修改文本"| PS
    
    %% 3. 处理完毕判定输出
    PS -->|"3. 本行处理完毕,准备输出"| OptionCheck
    
    OptionCheck -->|"是 (使用了 -i)"| FileOut
    OptionCheck -->|"否 (默认不加 -i)"| Output
  • sed 命令的整体组成

sed 命令的基本语法格式为:sed [选项] '地址定界 处理动作' 文件名

组成部分 常见参数 / 元素 核心作用与功能描述
全局选项 (Options) -n 取消默认输出:只打印经 p 指令显式指定的处理结果。
-i 直接修改原文件:不在终端仅做预览,直接将结果写入文件。
-e 多点编辑:允许在单条命令中指定多个 地址 动作 表达式。
-r / -E 启用扩展正则:支持 +?|() 等高级正则符号而无需转义。
地址定界 (Address) 数字 / 正则 / 范围 指定操作对象:定义处理动作作用于文本的哪些行(若省略则默认匹配所有行)。
处理动作 (Command) p / d / s / a / i / c 指定具体操作:决定对选中的行执行何种编辑逻辑(如替换、删除、追加等)。
  • 地址定界 (Address)

地址定界用于筛选出需要执行动作的目标行:

定界方式 语法格式 说明与示例
单行匹配 N 精准指定行号
例如 sed -n '5p' file.txt (仅处理第 5 行)
$ 代表最后一行
例如 sed -n '$p' file.txt (仅处理最后一行)
/pattern/ 正则匹配单行
例如 sed -n '/error/p' file.txt (仅处理包含 error 的行)
行号范围 N,M 指定起始到结束行
例如 sed -n '3,8p' file.txt (处理第 3 至第 8 行)
N,+M 起始行及后续 M 行
例如 sed -n '3,+5p' file.txt (处理第 3 行以及随后的 5 行,即 3-8 行)
正则范围 /pat1/,/pat2/ 模式匹配起始与结束
例如 sed -n '/BEGIN/,/END/p' file.txt (从匹配 pat1 的行开始,一直处理到匹配 pat2 的行)
步长匹配 N~M 指定起始行与递增步长
例如 sed -n '1~2p' file.txt (从第 1 行开始,每隔 2 行打印一次,即打印所有奇数行)
逻辑取反 地址! 对地址条件取反
例如 sed -n '1,5!p' file.txt (打印除了 1 到 5 行之外的所有行)
  • 处理动作 (Command)

配合地址定界对选中的文本行执行具体的编辑操作:

动作符号 动作名称 核心功能与使用说明 实用示例
p Print
(打印)
打印当前模式空间的内容。通常与全局选项 -n 搭配使用。 sed -n '1,3p' file.txt
d Delete
(删除)
删除模式空间中匹配的行,停止后续动作并立即读取下一行。 sed '/^#/d' file.txt
s Substitute
(替换)
查找并替换文本。
基本语法:s/源文本/目标文本/修饰符
常用修饰符:g
(全局替换)、i
(忽略大小写)。
sed 's/root/admin/g' file.txt
a Append
(行后追加)
在匹配到的目标行下方追加一行或多行指定文本。 sed '/IP/a GATEWAY=192.168.1.1' file.txt
i Insert
(行前插入)
在匹配到的目标行上方插入一行或多行指定文本。 sed '1i # Author: RedHat' file.txt
c Change
(整行替换)
将匹配到的整行文本直接替换为新的内容。 sed '3c SELINUX=disabled' file.txt
r Read
(读取导入)
读取指定外部文件的内容,并插入到匹配行的下方。 sed '/header/r /tmp/notice.txt' file.txt
w Write
(另存写入)
将匹配到的行写入并保存到指定的外部文件中。 sed -n '/error/w /tmp/error.log' app.log

文本转换工具 tr

tr(Translate)是一个轻量高效的字符转换工具,专门从标准输入中读取文本,用于对字符进行替换、删除、去重和大小写转换。

分类 / 维度 命令参数 / 语法 核心功能与运行机制 实用操作示例
标准字符替换 tr "SET1" "SET2" 一一对应替换。将输入中所有属于 SET1 的字符,对应替换为 SET2 中同位置的字符。 echo "hello world" | tr "a-z" "A-Z"
(将小写字母全部转为大写)
删除字符 -d "SET" 按字符删除Delete)。从文本中直接删除所有属于 SET 集合中的字符。 cat file.txt | tr -d "\r"
(去除 Windows 换行符 \r,转换为 Linux 格式)
压缩去重 -s "SET" 连续字符挤压去重Squeeze)。将连续重复出现的同类字符(如多个连续空格)压缩为一个。 df -h | tr -s ' '
(将多个连续空格压缩为单个空格,便于后续 cut 切割)
集合取反 -c / -C 补集匹配Complement)。针对 SET1 的补集(即不属于 SET1 的所有其他字符)进行操作。 echo "abc 123 !@#" | tr -cd "[:digit:]\n"
(保留数字和换行符,删除所有非数字字符)

Bash/变量/别名

Bash Shell

Shell 是 Linux 操作系统的命令行交互界面与脚本解释器,充当用户与内核之间的桥梁,负责接收指令并调动系统资源执行。

flowchart TD
    subgraph UserSpace ["用户 (最外层)"]
        style UserSpace fill:#ffffff,stroke:#333333,stroke-width:2px
        
        Cmd["<b>命令</b>"]
        
        subgraph ShellSpace ["Shell (中间层)"]
            style ShellSpace fill:#e3f2fd,stroke:#1976d2,stroke-width:2px
            
            Parse["<b>解析命令并传递给内核</b>"]
            
            subgraph KernelSpace ["Kernel (最内层)"]
                style KernelSpace fill:#bbdefb,stroke:#0d47a1,stroke-width:2px
                
                Exec["<b>执行动作</b>"]
            end
        end
    end

    Cmd -- "发起" --> Parse
    Parse -- "下发" --> Exec

Bash 的快捷键

分类 / 场景 快捷键 核心功能与操作机制 实用场景示例
光标快速移动 Ctrl + a 将光标快速跳至当前命令行的行首 输入长命令后想在最前面加 sudo
Ctrl + e 将光标快速跳至当前命令行的行尾 在长命令末尾继续追加参数。
Alt + b 将光标向(向后)移动一个完整单词。 快速跨单词微调参数。
Alt + f 将光标向(向前)移动一个完整单词。 快速向右跨单词定位。
文本快速编辑 Ctrl + u 剪切/删除光标位置至行首的所有字符。 输错半条指令时迅速清空左侧文本。
Ctrl + k 剪切/删除光标位置至行尾的所有字符。 删掉光标右侧多余的路径或参数。
Ctrl + w 剪切/删除光标左侧的一个单词(按空格分隔)。 快速撤销上一个输入的参数或路径。
Ctrl + y 粘贴最近一次由 Ctrl+u/k/w 剪切的文本。 将剪切的内容重新粘贴到新位置。
Ctrl + h 删除光标左侧的一个字符(等价于 Backspace)。 快捷删除单个字符。
命令历史与搜索 Ctrl + r 反向递进检索历史命令:输入关键词即可匹配历史记录。 快速调出极长的历史命令(连续按 Ctrl+r 可向上匹配更早的记录)。
Ctrl + g 退出 Ctrl+r 历史检索状态,恢复当前命令行。 放弃搜索并返回正常输入状态。
Alt + . 自动提取并插入上一条命令的最后一个参数 执行 mkdir test_dir 后,紧接着输入 cd 并按 Alt+. 自动填入 test_dir
控制与进程管理 Ctrl + c 终止当前进程(发送 SIGINT 信号),强行打断命令运行。 中断死循环脚本或卡住的命令。
Ctrl + z 挂起当前进程(发送 SIGTSTP 信号),将任务推入后台暂停。 暂停编辑临时切回 Shell(后续输入 fg 恢复)。
Ctrl + d 发送 EOF(文件结束符),在空行时等价于退出当前 Shell 终端(exit)。 快速注销 SSH 或退出子 Shell。
Ctrl + l 清屏(清空终端屏显),等价于执行 clear 命令。 屏幕太乱时快速刷新界面(原输入命令不受影响)。
Ctrl + s / Ctrl + q Ctrl+s 冻结终端屏幕输出;Ctrl+q 解冻恢复输出。 滚动大量日志时临时卡住屏幕查看内容。

通配符与扩展符号

符号 / 分类 语法类型 核心功能与运行机制 实用操作示例
通配符
(Pathname Expansion)
* 匹配零个或任意多个任意字符。 ls *.conf
(查找所有以 .conf 结尾的文件)
? 匹配恰好一个任意字符。 ls file?.txt
(匹配 file1.txt、fileA.txt,不匹配 file12.txt)
[...] 匹配括号内指定的任意单个字符 ls log[123].txt
(匹配 log1.txt、log2.txt 或 log3.txt)
ls [a-z]*.sh
(匹配以小写字母开头的脚本)
[^...][!...] 匹配不在括号内的任意单个字符(取反)。 ls file[^0-9].txt
(匹配第三个字符非数字的文件,如 fileA.txt)
{...} 匹配花括号中以逗号分隔的任意字符串组合 ls *.{png,jpg,jpeg}
(同时查找 png、jpg、jpeg 格式图片)
花括号扩展
(Brace Expansion)
{A,B,C} 字符串组合生成/生成序列,无需文件存在即可生成列表。 mkdir -p project/{src,bin,doc}
(一次性创建 src、bin、doc 三个目录)
{N..M} 生成连续的数字或字母序列(支持指定步长 {N..M..step})。 touch file{1..5}.txt
(批量创建 file1 到 file5)
echo {a..z}
(生成 26 个小写字母)
命令替换
(Command Substitution)
$(command) 执行命令并将输出替换回原位置(现代推荐标准语法)。 tar -zcvf log-$(date +%Y%m%m).tar.gz /var/log
算术扩展
(Arithmetic Expansion)
$((expression)) 计算整型算术表达式并输出结果。 echo $(( 10 + 5 * 2 ))
(输出 20)
NUM=$((NUM + 1))
变量扩展
(Parameter Expansion)
$VAR / ${VAR} 引用/替换变量的值;带 ${} 可防止变量名与后续字符混淆。 PREFIX="app"
echo "${PREFIX}_data"
(精准识别变量 PREFIX)
${VAR:-default} 默认值设置:若变量未设置或为空,则返回默认值。 echo "${PORT:-8080}"
(若 PORT 未赋值则使用 8080)

变量

变量本质上是一个用于存储和指向数据的“有名字的内存容器”。

简单来说,变量就像是一个贴了标签的盒子:

  • 变量名(标签):你给这个盒子起的名字(例如 AGEPATH),用来在后续代码中引用它。
  • 变量值(盒子里装的内容):存放在里面的具体数据(例如数字 25、文本 “root“ 或一个系统路径)。

本地变量与环境变量的区别

  • 本地变量仅在当前 Shell 进程有效。子 Shell 或新打开的终端无法访问该变量。
  • 环境变量对当前 Shell 及其所有子进程均有效。常用于传递系统配置信息。
graph TB
    %% Shell 进程 (包含子进程)
    subgraph ParentShell ["父 Shell 进程 (当前终端)"]
        style ParentShell fill:#f5f5f5,stroke:#616161,stroke-width:2px
        
        VAR1["<b>本地变量</b><br/>VAR1='local'"]
        VAR2["<b>环境变量</b><br/>export VAR2='env'"]

        %% 嵌套在父 Shell 内部的子 Shell 进程
        subgraph ChildShell ["子 Shell 进程"]
            style ChildShell fill:#e1f5fe,stroke:#0288d1,stroke-width:2px
            
            C_VAR1["❌ 无法获取 VAR1<br/><i>(未定义 / 为空)</i>"]
            C_VAR2["✅ 继承 VAR2<br/><i>(值为 'env')</i>"]
        end
    end

    %% 独立 Shell 进程 (完全隔离)
    subgraph OtherShell ["其它 Shell 进程"]
        style ParentShell fill:#f5f5f5,stroke:#616161,stroke-width:2px
        
        O_VAR1["❌ 无法获取 VAR1"]
        O_VAR2["❌ 无法获取 VAR2"]
    end

    %% 变量传递逻辑
    VAR1 -- "无法跨越<br/>(仅限当前进程)" --> C_VAR1
    VAR2 == "单向向下传递<br/>(继承环境变量副本)" ==> C_VAR2

    %% 独立进程隔离说明
    ParentShell -.- O_VAR1

定义、查看、引用变量

分类 快捷键 / 命令 核心功能与运行机制 实用操作示例
变量定义 NAME=value 定义局部自定义变量。在当前 Shell 进程内创建或修改变量(注意:= 两侧绝对不能有空格)。 IP="192.168.1.100"
PORT=8080
export NAME=value
export NAME
定义/提升为环境变量。将变量导出为全局环境变量,使其对当前 Shell 的所有子进程生效。 export PATH=$PATH:/usr/local/bin
export NODE_ENV="production"
read 交互式读取变量。接受用户键盘输入或标准输入,并将值赋给指定变量。
-p:指定提示信息
-s:隐式输入(如密码)
read -p "请输入用户名: " USERNAME
read -sp "请输入密码: " PASSWD
变量查看 echo $NAME 打印单个变量的值。最常用的变量提取查看命令。 echo $IP
echo ${PORT}
set 查看当前终端的所有变量。显示当前 Shell 环境中定义的所有变量(包含局部自定义变量、环境变量和函数)。 set | grep "IP="
set | head -n 20
env / printenv 查看当前所有环境变量。仅显示从导出并传递给子进程的环境变量(不包含普通局部变量)。 env
printenv PATH
(直接查看指定环境变量)
declare -p [NAME] 查看变量的属性和完整定义结构。显示变量的类型声明(如是否只读、是否数组)及精确赋值。 declare -p PATH
declare -p SUM
变量引用 $NAME 标准简单引用。提取并替换变量的值。 echo $IP
${NAME} 精确边界界定引用最推荐标准写法)。明确变量名的边界,防止变量名与紧随其后的文本相粘连造成歧义。 PREFIX="app"
echo "${PREFIX}_service"
(若写成 $PREFIX_service 会被识别为变量 $PREFIX_service)
${NAME:-default} 高级条件引用(默认值备选)。若变量未定义或为空,则临时返回 default,但变量本身值不改变。 echo "${TIMEOUT:-30}"
(若 TIMEOUT 未设置,则使用 30)

特殊的环境变量:系统变量

系统变量(通常表现为全局环境变量)是操作系统或操作系统下的 Shell 预先定义好的一套“通用配置项”。它们就像系统的全局“环境设置”,用来保存当前登录用户、操作系统环境、硬件平台以及程序运行所需的基础路径与语言偏好等关键信息。

常见的系统变量

系统变量名 核心功能与运行机制 默认典型值示例 实用操作 / 排错场景示例
PATH 可执行命令的搜索路径列表
当你在终端输入一个命令(如 lspython)时,系统会按照 PATH 中由冒号 : 分隔的目录顺序依次寻找对应的可执行文件,找到即止。
/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin 自定义软件配置
export PATH=$PATH:/opt/bin
(将 /opt/bin 加入全局搜索路径,无需输入绝对路径即可直接运行该目录下的工具)
HOME 当前登录用户的家目录(主目录)绝对路径
执行 cd(不加参数)或 cd ~ 时,Shell 会读取此变量跳转到对应的用户目录。
• 普通用户:/home/username
• root 用户:/root
脚本通用路径定位
cp config.json $HOME/.config/
(编写通用脚本时,将配置文件精准放至当前用户的家目录下)
USER 当前登录用户的用户名
记录当前正在操作终端或运行当前进程的账户标识。
rootzhangsan 脚本权限校验
if [ "$USER" != "root" ]; then
  echo "必须使用 root 权限运行!"
fi
SHELL 当前用户默认使用的 Shell 解释器绝对路径
系统在用户登录时读取此变量,为其分配指定的交互式命令行环境。
/bin/bash/bin/zsh 查看与兼容判断
echo $SHELL
(快速确认当前使用的是 Bash、Zsh 还是其他 Shell)
TMP / TEMP 临时文件存放目录
许多程序或脚本在运行过程中需要创建临时中间文件时,会优先读取此变量指向的路径。
/tmp/var/tmp 清洗/存取临时数据
echo "data" > $TMP/test.tmp
(Linux 环境下若未显式定义 TMP,程序通常默认回退使用 /tmp 目录)
LANG / LC_ALL 系统区域设置与语言/编码环境
LANG:设定系统的默认语言、地区和字符集编码(如 UTF-8)。
LC_ALL最高优先级重写变量,一旦设置会无视并覆盖所有 LANG 及其他 LC_* 细节配置。
zh_CN.UTF-8en_US.UTF-8 解决乱码/强制英文输出
LANG=en_US.UTF-8 log_tool
(排错时临时将输出语言切换为英文,方便检索报错信息)

永久定义变量

在 Linux 中,直接在命令行中使用 export VAR=value 定义的变量仅在当前终端会话中有效,关闭终端或重启系统后就会失效。

要实现永久定义,必须将变量定义写入到系统或用户的 Shell 启动配置文件 中。当 Shell 启动时,会自动读取这些文件并加载变量。

作用范围 适用场景 目标配置文件 特点与生效方式
全员/系统级 对系统上的所有用户及所有 Shell 进程均生效。 /etc/profile
/etc/profile.d/*.sh推荐
需要 root 权限。推荐在 /etc/profile.d/ 下新建独立的 .sh 脚本,便于管理和维护。
单用户级 仅对当前特定用户生效。 ~/.bashrc
~/.bash_profile
无需 root 权限,修改仅作用于当前用户的家目录。

别名

alias(别名)是 Shell 内置的核心功能,用于将一条较长的、复杂的或带有特定参数的命令映射为一个简短的名称,从而提高命令行操作效率,避免重复输入长命令。

分类 / 维度 语法格式 核心功能与运行机制 实用操作示例
定义别名 alias 别名='原命令' 创建临时别名。在当前 Shell 进程中为原命令指定新名称(注意:等号两侧绝对不能有空格,建议用单引号包裹原命令)。 alias ll='ls -alF'
alias c='clear'
查看别名 alias 显示当前所有别名。不带任何参数时,列出当前 Shell 环境中生效的所有别名映射。 alias
alias ll
(查看特定别名 ll 的具体定义)
取消别名 unalias 别名 移除指定别名。从当前 Shell 环境中删除指定的别名定义(-a 参数可清空所有别名)。 unalias ll
unalias -a
(取消所有别名)
绕过别名执行 \命令command 命令 强制执行原命令。忽略已定义的别名,直接调用系统的原生二进制文件/内置指令。 \cp -rf dir1 dir2
(绕过 cp -i 的覆盖提示,直接强制覆盖)

在命令行中直接执行 alias 定义的别名仅在当前终端窗口有效,关闭终端后即消失。要让别名永久生效,需将其写入配置文件 ~/.bashrc/etc/profile.d/*.sh 中。

  • 转义字符:去掉字符的特殊意义
    符号 / 分类 语法/机制名称 核心功能与运行机制 实用操作示例
    \ 反斜杠 (Backslash)
    (强转义单个字符)
    移除紧随其后单个字符的特殊含义,使其降级为普通字符(字面量);在行尾时作为续行符使用。 echo \$VAR
    (输出文本 $VAR,阻止变量扩展)
    touch file\ name.txt
    (将空格转义,创建带空格的文件名)
    echo "hello \
      world" (跨行拼接长命令)
    "" 双引号 (Double Quotes)
    (弱引用 / 局部转义)
    保留大部分字符的字面量,但允许某些特殊符号继续生效并被解析。
    • 允许生效的符号:$(变量/算术扩展)、\(转义)、!(历史命令)、` `(命令替换)。
    NAME="Linux"
      echo "Hello $NAME"
    (输出 Hello Linux)
    echo "Cost: \$100"
    (配合 \ 转义美元符号,输出 Cost: $100)
    '' 单引号 (Single Quotes)
    (强引用 / 完全屏蔽)
    彻底关闭所有字符的特殊含义,括号内所有内容一律按纯文本原样处理(没有任何符号能逃过单引号的屏蔽,甚至连 \ 在单引号内部也只代表普通的反斜杠字符)。 NAME="Linux"
      echo 'Hello $NAME'
    (输出文本 Hello $NAME)
    echo 'a\nb $1'
    (原样输出 a\nb $1)

系统的进程管理

进程概述

  • 进程(Process)
    进程是操作系统中正在运行的一个程序的实例。它不仅包含程序的代码,还拥有独立的内存空间、系统资源(如打开的文件描述符、网络端口)以及 CPU 执行状态。程序本身只是存放在磁盘上的静态文件,只有被装载到内存中并由 CPU 执行时,才成为了动态的进程。

  • 父进程(Parent Process)
    在 Linux/Unix 系统中,除了系统启动时的初始进程外,所有新进程都是由已存在的进程创建出来的。那个发起创建指令、生成新进程的原始进程就是父进程。父进程负责管理子进程的生命周期,并在子进程结束时收集其退出状态信息。

  • 子进程(Child Process)
    由父进程通过系统调用(如 fork())派生或创建出来的新进程就是子进程。子进程在刚创建时会继承父进程的大部分环境属性(如环境变量、当前工作目录、打开的文件等),但它拥有自己独立的内存空间和唯一的进程标识符。

  • 进程标识符(Process ID / PID)
    进程 ID 是操作系统为每一个运行中的进程分配的唯一数字编号。系统使用 PID 来精准识别、追踪和管理特定的进程。你可以通过 PID 向指定进程发送信号(例如使用 kill <PID> 来终止某个进程)。

  • PID 1(初始进程 / Init Process)
    PID 1 是 Linux 系统内核启动后创建的第一个用户态进程(在现代 Linux 系统中通常是 systemd)。它是系统中所有其他进程的“老祖宗”或终极父进程。PID 1 承担着初始化系统服务、管理系统状态以及回收无人管辖的“孤儿进程”等关键职责。

  • 权限继承(Permission Inheritance)
    当父进程创建子进程时,子进程默认会继承父进程的安全上下文与访问权限,包括运行该进程的用户身份(UID)、所属用户组(GID)以及文件创建掩码(umask)。这意味着子进程所能访问的系统资源和执行的操作,受限于其父进程被赋予的权限范围。

  • 特殊进程类型

    • 孤儿进程(Orphan Process)
      当父进程在子进程尚未结束前就提前退出或崩溃了,这个还在继续运行的子进程就会变成孤儿进程。孤儿进程不会一直在系统中“游荡”,因为系统中的 PID 1(初始进程)会自动接管这些失去父进程的进程,成为它们的新父进程,并在它们最终退出时妥善清理相关资源。
    • 僵尸进程(Zombie Process)
      当一个子进程已经执行完毕并释放了大部分内存和资源,但其父进程尚未通过调用 wait()waitpid() 来读取它的退出状态时,这个已经“死亡”的进程残骸就会变成僵尸进程。僵尸进程不再占用 CPU 和内存,但在进程表中仍然会保留一个位置(占用一个 PID)。如果系统中积累了大量僵尸进程且父进程迟迟不回收,可能会耗尽系统的 PID 资源,导致新进程无法创建。

查看与检索进程

静态进程查看 ps

语法与核心参数 核心功能与运行机制 实用操作示例
ps aux
(BSD 风格)
静态捕获系统当前时刻的进程快照。打印当前瞬间所有进程的详细状态(CPU/内存占用、启动时间、执行命令等)。 ps aux | grep nginx
(查找与 nginx 相关的进程)
ps -ef
(System V 风格)
标准全格式显示进程及其层级。清晰列出所有进程的 UIDPIDPPID(父进程 ID)及启动参数。 ps -ef | grep sshd
(查看 SSH 进程及其父子继承关系)
ps -o 自定义字段输出。仅打印指定的列,便于脚本提取特定属性。 ps -eo pid,ppid,user,%cpu,%mem,cmd
(定制提取关键维度数据)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
USER         PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root 1 0.0 0.1 167888 9600 ? Ss Sep16 0:02 /sbin/init

# USER : 进程所有者的用户名 (UID)
# PID : 进程标识符 (Process ID)
# %CPU : 进程自启动以来占用 CPU 的百分比
# %MEM : 进程占用物理内存 (RAM) 的百分比
# VSZ : 虚拟内存大小 (Virtual Memory Size,单位:KB),包含进程可访问的所有内存(含共享库及# 未调入内存页)
# RSS : 常驻内存大小 (Resident Set Size,单位:KB),进程实际占用的非交换 (Non-Swapped) 物# 理内存大小
# TTY : 进程运行的终端类型(? 表示无终端的后台守护进程,tty1-6 为本地终端,pts/N 为远程 # SSH/虚拟终端)
# STAT : 进程当前运行状态标识符(详见下方“STAT 状态代码表”)
# START : 进程启动的具体时间(若启动超过 24 小时则仅显示日期)
# TIME : 进程累计消耗 CPU 的总时间(格式为 MM:SS 或 HH:MM:SS)
# COMMAND : 启动进程的完整命令行指令及参数

动态性能监控 top

语法与核心参数 核心功能与运行机制 实用操作示例
top 动态实时监控系统进程与资源。按固定时间间隔(默认 3 秒)刷新 CPU、内存占用以及各进程的实时排名。 top
(直接进入交互式动态界面)
top -p <PID> 精准监控指定进程。仅追踪特定 PID 进程及其线程的资源消耗。 top -p 1234
(监控 PID 为 1234 的进程)
top -u <USER> 过滤指定用户的进程。仅显示特定用户发起的进程列表。 top -u nginx
(仅监控 nginx 用户的进程)
top -b -n 1 批处理模式(Batch mode)。不启动交互界面,仅输出 1 次当前快照,常用于脚本分析或日志留存。 top -b -n 1 > top_snapshot.txt
(保存当前资源占用快照)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
top - 19:43:37 up 1 day,  4:12,  2 users,  load average: 0.15, 0.08, 0.02
Tasks: 215 total, 1 running, 214 sleeping, 0 stopped, 0 zombie
%Cpu(s): 1.5 us, 0.5 sy, 0.0 ni, 97.8 id, 0.1 wa, 0.0 hi, 0.1 si, 0.0 st
MiB Mem : 7812.5 total, 3150.2 free, 2410.8 used, 2251.5 buff/cache
MiB Swap: 2048.0 total, 2048.0 free, 0.0 used. 5100.1 avail Mem
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
1234 mysql 20 0 1850.4m 450.2m 18.5m S 2.3 5.6 12:34.56 mysqld

# 【第一行:系统基本信息与负载】
# 19:43:37 : 当前系统时间
# up 1 day... : 系统运行时长(已连续运行 1 天 4 小时 12 分钟)
# 2 users : 当前登录系统的总会话/用户数
# load average : 系统在过去 1分钟、5分钟、15分钟 内的平均负载(单核 CPU 达到 1.0 表示满载)
#
# 【第二行:任务/进程统计】
# Tasks : 进程总量情况(total: 总进程数, running: 运行中, sleeping: 休眠中, stopped: 暂停, zombie: 僵尸进程数)
#
# 【第三行:CPU 状态(所有 CPU 核心平均值)】
# us (user) : 用户态进程占用 CPU 百分比
# sy (system) : 内核态/系统进程占用 CPU 百分比
# ni (nice) : 调整过 Nice 优先级的用户进程占用 CPU 百分比
# id (idle) : 空闲 CPU 百分比
# wa (iowait) : 等待磁盘/网络 I/O 操作完成占用的 CPU 时间百分比(数值偏高说明磁盘性能存在瓶颈)
# hi (hardware): 硬中断 (Hardware IRQ) 占用 CPU 时间百分比
# si (software): 软中断 (Software Interrupts) 占用 CPU 时间百分比
# st (steal) : 被虚拟化宿主机“偷走”的 CPU 时间百分比(虚拟机环境独有)
#
# 【第四行与第五行:内存与交换分区 (Mem / Swap)】
# total : 物理内存 / 交换分区总容量
# free : 未使用的空闲内存容量
# used : 已占用的内存容量
# buff/cache : 用于内核缓冲区 (Buffers) 和页面缓存 (Page Cache) 的内存容量
# avail Mem : 预计在不使用 Swap 的情况下,新程序可获得的实际可用物理内存容量

# 【进程状态列表区】
# PID : 进程标识符
# USER : 进程所有者的用户名
# PR : 进程调度的动态优先级 (Priority),数值越小优先级越高(RT 表示实时进程 Real-Time)
# NI : 进程的静态 Nice 值(范围 -20 到 19,越小代表优先级越高,负值仅 root 可设)
# VIRT : 进程申请的虚拟内存总量(单位:KB/MB/GB)
# RES : 进程使用的未被换出的物理内存大小(与 ps 命令的 RSS 一致)
# SHR : 进程使用的共享内存大小 (Shared Memory,如动态链接库占用的内存)
# S : 进程当前状态(R: 运行中, S: 休眠, D: 不可中断休眠, Z: 僵尸, T: 跟踪/停止)
# %CPU : 进程上次刷新以来占用的 CPU 利用率(多核环境下单进程占用单核 100% 可超过 100%)
# %MEM : 进程占用的物理内存百分比
# TIME+ : 进程启动后占用 CPU 的累计百分之一秒时间(格式:分:秒.厘秒)
# COMMAND : 进程名称或启动指令

进程检索工具 pgrep/pidof

命令 匹配机制与特点 常用选项参数 实用操作示例
pgrep 灵活性高(支持正则/模糊匹配)
根据进程名称的关键字或正则表达式检索进程,默认输出所有匹配到的 PID 列表。
-l:同时列出 PID 和进程名称
-a:列出 PID 并显示完整的命令行参数
-u:限定指定用户的进程
-f:匹配完整的命令行路径而不仅是进程名
pgrep -a nginx
(列出包含 nginx 的进程 PID 及完整启动命令)
pgrep -u root sshd
(查找 root 用户运行的 sshd 进程 PID)
pidof 精确度高(必须精准匹配程序名)
只接受二进制可执行文件的精确名称(或绝对路径),精准查找并返回该程序对应的 PID。
-s:单次匹配,仅返回第一个找到的 PID
-o:忽略/排除指定的 PID(omit
pidof nginx
(精准获取 nginx 主进程和工作进程的所有 PID)
kill -9 $(pidof httpd)
(结合杀进程指令,精准杀死 httpd 服务)

进程间通信

在 Linux 系统中,每个进程拥有独立的虚拟地址空间,进程间无法直接访问彼此的内存。为了实现数据交换与协作,操作系统提供了多种进程间通信(Inter-Process Communication, IPC)机制,例如管道、信号(Signal)、共享内存、消息队列以及 Socket 套接字等。

常用系统信号

信号(Signal) 是 Linux 系统中最古老、轻量级的进程间异步通知机制。内核或进程可以向目标进程发送特定信号,强制其触发默认或自定义的处理逻辑。

可通过 kill -l 命令查看完整信号列表,以下为 RHCE 运维与开发中常用的系统信号:

信号编号 信号名称 默认动作 核心用途与运行机制 实用指令 / 触发场景
1 SIGHUP 终止进程 挂起 / 重载配置。终端断开时通知进程;常用于通知守护进程重新加载配置文件而不重启服务。 kill -1 <PID>systemctl reload
2 SIGINT 终止进程 中断信号。通常由前台交互终端发起,请求进程平滑停止。 键盘按下 Ctrl + c
9 SIGKILL 强制终止 无条件杀死进程无法被进程捕获、忽略或阻塞,由内核直接强行销毁进程。 kill -9 <PID> (高危/最后手段)
15 SIGTERM 终止进程 软件终止信号kill 命令的默认动作)。允许被捕获,给进程留出时间清理资源并优雅退出。 kill <PID>systemctl stop
20 SIGTSTP 暂停/挂起 终端停止信号。由终端发送的暂停请求,与 SIGSTOP 类似但允许被进程捕获 键盘按下 Ctrl + z

发送信号的工具

命令 匹配机制与目标定位 核心功能与运行机制 实用操作示例
kill 精确 PID 定位
只接受数字形式的进程 ID(PID)作为参数。
向单个或指定多个 PID 发送特定信号(默认为 SIGTERM -15)。由于只依赖数字 PID,它是最精准、最安全的信号发送命令。
-1 (-SIGHUP):请求进程重新加载配置文件
-9 (-SIGKILL):强制杀死进程(内核直接销毁)
-15 (-SIGTERM):默认信号,请求进程优雅退出
-l:列出系统支持的所有信号列表
kill 7926
(向 PID 7926 发送 SIGTERM 请求优雅退出)
kill -9 7926
(发送 SIGKILL 强制杀死进程)
kill -1 6568
(发送 SIGHUP 命令重载配置)
killall 精确进程名定位
接收二进制可执行文件的完整名称
按进程名批量杀死同名进程。扫描所有运行中的进程,向所有进程名完全匹配的进程统一发送信号。
-i:交互式模式,杀进程前逐个提示确认
-u <USER>:限定仅杀属于指定用户的进程
-s <SIGNAL> / -信号编号:指定发送的信号(如 -9
-w:等待所有被杀的进程完全退出后命令才返回
killall httpd
(杀死所有名为 httpd 的进程)
killall -9 nginx
(强制杀死所有 nginx 进程)
killall -u devops httpd
(仅杀死 devops 用户运行的 httpd 进程)
pkill 高级条件/正则匹配定位
支持根据进程名模糊/正则匹配用户终端等多种维度筛选。
按高级维度批量筛选并发送信号。内部匹配逻辑与 pgrep 一致,能根据多维约束精准清洗特定上下文的进程。
-u <USER>:匹配指定有效用户(UID/用户名)的进程
-t <TTY>:匹配指定控制终端(如 pts/1)上的进程
-f:匹配完整的命令行路径和参数,而不仅是进程名
-9:强行杀死匹配筛选条件的所有进程
pkill -u devops
(踢掉/结束 devops 用户的所有进程)
pkill -t pts/1
(终止连接在终端 pts/1 上的所有进程)
pkill -f "python3 main.py"
(按完整命令行匹配并杀掉进程)

后台作业

后台作业(Background Job) 是指在 Linux Shell 中被推到“后台”运行、不占用当前终端命令行交互界面的进程或任务。

当你将一个命令放到后台运行时,它可以在操作系统底层默默执行,而当前的终端会立即恢复响应,允许你继续输入并执行其他命令。
如果没有对输出进行重定向(如 > output.log 2>&1),后台作业打印的信息依然会直接弹在你的终端屏幕上,可能会打断你当前正在输入的命令(建议配合重定向使用)。

命令 / 快捷键 匹配机制与作业定位 核心功能与运行机制 实用操作示例
命令 & 命令后缀标记 直接在后台启动进程。执行命令时在末尾加上 &,使命令不在前台占用终端交互界面,直接以后台作业形式运行。但在默认情况下,当终端窗口(SSH 会话)关闭时,该作业仍可能收到 SIGHUP 信号而终止。 python3 script.py &
(在后台启动 Python 脚本,释放终端控制权)
jobs 当前终端会话 查看当前 Shell 终端管理的所有后台作业。列出当前终端下的作业编号(Job ID)、运行状态(Running / Stopped)以及对应的启动指令。
-l:同时显示作业编号对应的真实进程 PID
-r:仅列出处于运行中(Running)状态的后台作业
-s:仅列出处于挂起/停止(Stopped)状态的后台作业
jobs -l
(查看作业编号、PID 及对应命令)
fg 作业编号定位 (%JID)
(若不带参数,默认作用于当前/最近的作业 %+)
将后台作业调至前台运行。恢复前台交互控制,使进程重新接入当前终端的标准输入与输出。 fg %1
(将编号为 1 的后台作业转到前台继续运行)
fg
(将默认关联的最近一个作业转到前台)
Ctrl + z 当前前台作业 将前台运行的作业挂起(Suspend)并推入后台。向当前前台进程发送 20) SIGTSTP 信号,立即暂停进程执行并将控制权交还终端。注意:此时进程处于停止(Stopped)状态,并未在后台继续运行,需配合 bg 恢复。 在运行长耗时命令时按 Ctrl+z
(暂停前台任务并返回 Shell 提示符)
bg 作业编号定位 (%JID)
(若不带参数,默认作用于最近被挂起的作业 %+)
让后台处于挂起状态的作业恢复运行。向指定的 Stopped 状态作业发送 18) SIGCONT 信号,使其在后台继续默默执行(保持 Running 状态)。 bg %1
(恢复编号为 1 的挂起作业,让其在后台继续运行)
kill %JID 作业编号定位 (%JID)
(注意编号前必须带有 % 符号)
通过作业编号(Job ID)结束后台任务。由于 kill 默认接受 PID 参数,使用 % 前缀可明确告知系统该数字为 jobs 列表里的作业编号而非系统 PID。
kill %1:发送 15) SIGTERM 请求优雅终止
kill -9 %1:发送 9) SIGKILL 强制销毁该作业
kill %1
(结束编号为 1 的后台作业)
kill -9 %2
(强制杀死编号为 2 的后台作业)
nohup 命令前缀包装 忽略挂起信号 (SIGHUP -1)。包装目标命令,使其脱离终端挂断事件的影响。即便 SSH 会话断开或终端关闭,进程仍能在后台持续运行。默认会将标准输出与错误重定向输出到当前目录的 nohup.out 文件中。 nohup python3 script.py &
(永久脱离终端,在后台挂起稳定运行)
disown 作业编号定位 (%JID) 从 Shell 的作业表中移除指定的后台任务。移除后该任务不再受当前 Shell 会话控制,关闭终端时 Shell 也不会向其发送 SIGHUP 信号,适合补救忘记加 nohup 启动的后台进程。
-h:不移除作业,仅标记使其忽略 SIGHUP 信号
-a:作用于当前终端的所有后台作业
python3 script.py &
disown -h %1
(将已运行的 1 号作业标记为忽略终端挂断信号)

后台作业默认仍然是当前登录 Shell 的子进程,并归入当前 Shell 的作业列表(可通过 jobs 查看)。默认情况下,如果你直接关闭终端窗口或断开 SSH 连接,当前终端会向其所有的后台作业发送 SIGHUP(挂断信号),导致后台作业随之终止。
nohup 命令 重定向 & 可以让后台作业不会随着终端退出而退出。
如果不指定重定向,则默认重定向到 nohup.out

网络基础和网络服务端口

IP 地址

IP 地址(Internet Protocol Address,网际协议地址)是分配给网络中每台设备(如计算机、服务器、路由器等)的数字标识符。它类似于现实生活中的门牌号或电话号码,用于在网络通信中唯一定位设备并路由数据包。

常见的 IP 地址分为两大版本:

  • IPv4:采用 32 位二进制数,通常写成四组十进制数字(如 192.168.1.1)。
  • IPv6:采用 128 位二进制数,用于解决 IPv4 地址枯竭问题(如 fe80::1)。

IP 地址的组成

地址(以最常见的 IPv4 为例)是一个 32 位的二进制数,通常写成“点分十进制”形式(例如 192.168.1.1)。它由两个核心部分组成:

  • 网络地址(Network ID): 标识设备所在的网络/子网,类似于邮寄地址中的“城市与街道”。
  • 主机地址(Host ID): 标识该特定网络内的具体设备,类似于“门牌号”。

NAT 技术

NAT(Network Address Translation) 是一种将私有(局域网)IP 地址转换为公有(广域网)IP 地址的网络技术。

  • 核心作用: 解决 IPv4 地址枯竭问题,同时隐藏内部网络结构以提升网络安全性。
  • 主要应用形态(NAPT / 端口复用): 多个局域网设备(如 192.168.1.X)共享同一个公网 IP 访问外网。NAT 设备(如路由器)通过给不同设备映射不同的源端口号,来区分和转发接收到的回应数据。

子网掩码

子网掩码(Subnet Mask)是用于结合 IP 地址一起使用的 32 位二进制数值,主要用来区分一个 IP 地址中的网络地址主机地址,并明确当前 IP 所在的子网范围。

子网掩码的组成

  • 二进制结构:由连续的 1 和连续的 0 组成,全长 32 位(4 个字节)。
    • 前半部分全为 1:对应 IP 地址中的网络号(Network ID)。
    • 后半部分全为 0:对应 IP 地址中的主机号(Host ID)。
    • 注意10 必须是连续的,不能交叉或交替出现。
  • 常见表达方式
    • 点分十进制:例如 255.255.255.0
    • CIDR 斜线记法:例如 /24,表示掩码的前 24 位全为 1

子网掩码的作用

  1. 划分网络与主机区域:通过与 IP 地址进行**按位与(AND)**运算,提取出具体的网络地址。
  2. 判断同网段通信:设备在发送数据包前,通过对比目标 IP 与本地 IP 的网络地址:
    • 相同:判定为同一局域网(同网段),直接通过 MAC 地址进行二层直连通信。
    • 不同:判定为跨网段,需要将数据转发给默认网关(Router)进行三层路由。
  3. 划分子网与灵活规划:借助变长子网掩码(VLSM),可将大网段切分为多个较小的子网,减少广播域范围,提高网络安全与 IP 地址利用率。

默认网关

默认网关(Default Gateway)通常由跨网段出口设备(如路由器或三层交换机)担任,它是局域网设备通往其他外部网络(如其他子网或互联网)的“出入口”与“翻译官”。

  • 物理实体:具备三层路由转发能力的网络设备接口(如家用路由器的 LAN 口 IP,或企业核心交换机的 VLAN 虚接口 IP)。
  • 逻辑属性
    • IP 地址:必须与本地设备处于同一网段(例如本地 IP 为 192.168.1.100/24,网关通常设定为 192.168.1.1192.168.1.254)。
    • MAC 地址:设备在进行跨网段通信时,数据包的目标 IP 保持不变,但二层目标 MAC 地址会指定为网关的 MAC 地址。

DNS 地址

DNS(Domain Name System,域名系统) 是互联网最重要的基础服务之一,通常被形象地比喻为 “互联网的电话簿”。

在网络世界中,计算机之间互相通信只认 IP 地址,但人类很难记住这一串串毫无规律的数字。DNS 的核心作用,就是把人类容易记忆的“域名”(如 baidu.com)精准翻译成计算机能够识别的“IP 地址”

sequenceDiagram
    autonumber
    actor U as 👤 用户
    participant L as 🌐 DNS (如 8.8.8.8)
    participant R as 🌳 根服务器
    participant T as 🏢 TLD (.com)
    participant A as 🏛️ 权威 DNS

    U->>L: 查 www.baidu.com
    Note over L: 无缓存,开始迭代查询
    L->>R: 1. 查 www.baidu.com
    R-->>L: 指路: 去问 .com
    L->>T: 2. 查 www.baidu.com
    T-->>L: 指路: 去问 baidu.com
    L->>A: 3. 查 www.baidu.com
    A-->>L: 答案: 180.101.50.1
    L-->>U: 返回 IP (存缓存)

网卡设备命名

在 Linux 系统中,网络接口(网卡)的命名方式主要经历了从传统命名到可预测命名(Predictable Network Interface Names)演进。

传统命名方式:eth0, eht1, eth2wlan0, wlan1

  • 命名规则:以网络设备类型名称加上从 0 开始的递增数字标识,如 eth0eth1wlan0 等。
  • 运行机制:内核在系统引导启动时,按照硬件被探测到(Enumerated)的先后顺序依次分配编号。
  • 存在问题
    • 不稳定与非确定性:多网卡环境下,当新增/移除网卡或 PCI 插槽顺序变更时,内核检测硬件的顺序可能发生变化,导致原先的 eth0 在重启后变为 eth1,引发网络配置失效。

可预测命名方式:ens33, enp3s0, wlp2s0

systemd / udev 引入的标准命名规则(Red Hat Enterprise Linux 7 及以上版本默认采用),旨在保证网卡名称在硬件变动或系统重启后始终保持绝对稳定。

  • 命名前缀(表示设备类型)
    • en:以太网卡(Ethernet)
    • wl:无线局域网卡(WLAN)
    • ww:无线广域网卡(WWAN / 移动蜂窝网)
  • 定位后缀(表示硬件物理位置/固件属性)
    • o<number>:板载设备(On-board),如 eno1
    • s<slot>:PCI 扩展插槽(Hotplug slot),如 ens3
    • p<bus>s<slot>:PCI 拓扑总线位置与插槽,如 enp2s0
    • x<MAC>:基于硬件 MAC 地址命名,如 enx78e7d1ea46da

网络相关管理工具

查看网络

查询需求 命令 / 语法 核心功能与运行机制 实用输出特征 / 示例
查看 IP 和子网掩码 ip addr show
(或缩写 ip a)
现代 Linux 标准网络工具(来自 iproute2 包)。用于显示所有已激活/未激活网卡的 IP 地址、掩码及网络状态。 ip a show enp2s0
(输出如 inet 192.168.1.100/24,斜线后的 24 即表示掩码为 255.255.255.0)
ifconfig 传统网络工具(来自 net-tools 包)。以传统块状格式输出网卡信息(部分新版系统默认未安装)。 ifconfig enp2s0
(显式输出 inet 192.168.1.100 netmask 255.255.255.0)
查看 DNS 地址 cat /etc/resolv.conf 静态查询系统域名解析配置文件。直观列出当前系统指向的 DNS 上游服务器地址。 cat /etc/resolv.conf
(查看输出中的 nameserver 8.8.8.8 行)
nmcli dev show NetworkManager 动态查询。查看由 DHCP 自动获取或手动指定的动态 DNS 配置。 nmcli dev show | grep DNS
(提取当前生效的 IP4.DNS[1] 记录)
resolvectl status systemd-resolved 动态查询。在采用 systemd 域名解析服务的系统(如 RHEL 8/9、Ubuntu)中查看各接口绑定的 DNS。 resolvectl status
(查看指定网卡接口下的 DNS Servers 行)
查看网关地址 ip route show
(或缩写 ip r)
现代标准路由表查询。列出当前内核路由表,其中 default 标注的条目即为默认网关。 ip route show
(输出如 default via 192.168.1.1 dev enp2s0,其中 192.168.1.1 即为网关)
route -n 传统路由表查询。以网格形式列出路由表,-n 参数表示直接显示 IP 而不进行域名反解析。 route -n
(目标 0.0.0.0 对应的 Gateway 列即为默认网关)

临时配置网络

linux上的网络服务:

  • network:Linux 传统的网络服务,主要通过读取 /etc/sysconfig/network-scripts/ifcfg-* 静态配置文件,在系统启动时一次性初始化固定网络接口。
  • NetworkManager:现代 Linux 默认的动态网络管理守护进程,能够自动感知网络状态变化,并提供 nmclinmtui 等丰富工具来统一、动态地配置和管理各种物理及虚拟网络连接。
章节与操作 工具 / 语法 核心功能与运行机制 实用操作示例
临时配置网络地址 ifconfig ifconfig <网卡名> <IP> netmask <掩码> 传统网络配置方式(来自 net-tools)。直接向内核网络接口设置 IP 地址与子网掩码。操作立即生效,但重启系统或重启网络服务后失效 ifconfig eth0 192.168.1.100 netmask 255.255.255.0
(临时设置 eth0 的 IP 和子网掩码)
ifconfig eth0 up/down
(临时启用/禁用网卡)
临时配置网络地址 ip(推荐) ip addr {add|del} <IP/CIDR> dev <网卡名> 现代 Linux 标准配置方式(来自 iproute2,RHCE 推荐)。支持在一个网线上绑定多个 IP(IP 别名/多 IP 模式)。操作立即生效,重启后失效 ip addr add 192.168.1.100/24 dev enp2s0
(给 enp2s0 添加临时 IP)
ip addr del 192.168.1.100/24 dev enp2s0
(删除该临时 IP)
临时配置 DNS 地址 编辑 /etc/resolv.conf 直接修改内核域名解析配置文件。在文件头部添加 nameserver 条目。配置立即对全局生效,但在启用了 NetworkManager 的系统上,重启网络或系统后会被覆盖。 echo "nameserver 8.8.8.8" >> /etc/resolv.conf
(追加临时 DNS 地址)
echo "nameserver 114.114.114.114" > /etc/resolv.conf
(覆盖设置主 DNS)
临时添加 / 删除路由 route route {add|del} ... 传统路由表配置工具(来自 net-tools)。用于向内核路由表临时注入或剔除网段路由及默认网关。操作立即生效,重启后失效 route add default gw 192.168.1.1
(临时添加默认网关)
route add -net 10.0.0.0/8 gw 192.168.1.254
(添加指向 10.0.0.0/8 网段的静态路由)
route del default
(删除默认网关)
临时添加 / 删除路由 ip route(推荐) ip route {add|del} ... 现代 Linux 路由配置工具(来自 iproute2,RHCE 推荐)。高精度的内核路由表操控工具,语法更直观。操作立即生效,重启后失效 ip route add default via 192.168.1.1 dev enp2s0
(临时添加默认网关)
ip route add 10.0.0.0/8 via 192.168.1.254 dev enp2s0
(添加特定网段静态路由)
ip route del 10.0.0.0/8
(删除该静态路由)

示例:多网关的实际应用场景

flowchart TD
    %% 节点定义
    Internet["互联网 (Internet)"]
    
    subgraph RouterA_Group ["路由器 A (互联网网关)"]
        RouterA["WAN 口: 接运营商光猫<br/>LAN 口: 192.168.1.1"]
    end

    Switch["二层交换机 (局域网)"]

    subgraph PC_Group ["你的电脑 (单网口)"]
        PC["网口: 插交换机<br/>IP 1: 192.168.1.100<br/>IP 2: 192.168.2.100"]
    end

    subgraph RouterB_Group ["路由器 B (专网网关)"]
        RouterB["LAN 口: 192.168.2.1<br/>WAN/OPT口: 接公司专线"]
    end

    subgraph Server_Group ["公司总部内网服务器"]
        Server["网口: 接总部交换机<br/>IP: 10.0.0.0/24"]
    end

    %% 连接关系与接口标注
    Internet == "光纤" ==> RouterA
    RouterA -- "LAN 1口" --- Switch
    Switch -- "交换机 1口" --- PC
    Switch -- "交换机 2口" --- RouterB
    RouterB == "专线 / VPN 隧道" ==> Server

    %% 样式调整
    style Internet fill:#f9f9f9,stroke:#333,stroke-width:1px
    style Switch fill:#e1f5fe,stroke:#0288d1,stroke-width:2px
    style PC_Group fill:#fff3e0,stroke:#f57c00,stroke-width:1px
    style RouterA_Group fill:#e8f5e9,stroke:#388e3c,stroke-width:1px
    style RouterB_Group fill:#e8f5e9,stroke:#388e3c,stroke-width:1px
    style Server_Group fill:#f3e5f5,stroke:#7b1fa2,stroke-width:1px

将发往 10.0.0.0/24 网段的流量,强制发给路由器 B (192.168.2.1)

1
2
ip route add 10.0.0.0/24 via 192.168.2.1
route add -net 10.0.0.0 netmask 255.255.255.0 gw 192.168.2.1

在上面的例子中,将路由器 A(192.168.1.1)作为唯一的“默认网关(Default Gateway)”,并且把路由器 B (192.168.2.1)跃点数调至高(即低优先级),那么访问互联网时会自动走网关A,访问 10.0.0.0/24 网段的IP时自动走网关B。

永久修改路由 nmtui/nmcli

  • nmtui(NetworkManager Text User Interface)是一个基于文本的伪图形界面工具。它提供直观的菜单导航,允许你通过键盘方向键、Tab 键和回车键来添加、修改或激活网络连接,非常适合不熟悉命令行参数的新手或在临时排错时快速配置。
  • nmcli(NetworkManager Command Line Interface)则是一个功能完备的纯命令行控制工具。它可以直接与 NetworkManager 守护进程通信,实现对网络设备和连接配置的高精度控制。由于其支持脚本自动化、易于精准记录且能配置复杂的网络结构(如链路聚合 Bond、网桥 Bridge、VLAN 等),它是生产环境运维和 RHCE 考试中的绝对主力工具。

在 Red Hat Enterprise Linux (RHEL) 系统中,NetworkManager 是默认的网络管理服务。理解其底层抽象概念(Device 与 Connection)是掌握网络配置的前提。

  • Device(设备) 代表系统内核识别到的物理或虚拟网卡硬件(例如 enp2s0eth0wlan0)。它仅对应网络通信的物理/逻辑载体,负责实际的数据包收发,体现的是硬件的状态(如是否插好网线、Link 状态是否正常),设备本身并不直接保存具体的网络参数。
  • Connection(连接) 则是一套逻辑配置文件。它包含了网卡工作所需的所有静态/动态网络参数,例如 IP 地址、子网掩码、默认网关、DNS 服务器、MAC 地址绑定以及开机自动连接属性(autoconnect)。这些配置文件持久化存储在系统的 /etc/NetworkManager/system-connections/ 目录下。
nmcli connection 核心子命令列表
子命令 命令语法 核心功能与关键参数 实用示例
show nmcli c show [--active | <连接名>] 查看网络连接。不加参数列出所有连接,指定名字显示详细配置。
--active:仅列出当前激活的连接
nmcli c show
nmcli c show --active
nmcli c show eth0-static
add nmcli c add type <类型> ifname <网卡名> con-name <连接名> [参数 值] 新建连接并永久写入磁盘。
type:网络类型(如 ethernet
ipv4.methodmanual(静态)或 auto(DHCP)
ipv4.addresses / ipv4.gateway / ipv4.dns:指定静态网络参数
nmcli c add type ethernet ifname enp2s0 con-name enp2s0-dhcp
nmcli c add type ethernet ifname enp2s0 con-name enp2s0-static ipv4.method manual ipv4.addresses 192.168.1.100/24 ipv4.gateway 192.168.1.1 ipv4.dns 8.8.8.8 autoconnect yes
modify nmcli c modify <连接名> [+|-]<参数> <值> 修改已有连接参数,更改后需 up 生效。
+ / - 前缀:用于追加或移除特定参数(如 DNS)
nmcli c modify enp2s0-static ipv4.addresses 192.168.1.200/24
nmcli c modify enp2s0-static +ipv4.dns 114.114.114.114
up nmcli c up <连接名> 激活并应用连接到网卡,使配置立即生效。 nmcli c up enp2s0-static
down nmcli c down <连接名> 断开指定的网络连接,不删除配置文件。 nmcli c down enp2s0-static
reload nmcli c reload 重新加载磁盘上的 Keyfile 或 ifcfg 配置文件。 nmcli c reload
delete nmcli c delete <连接名> 从系统及磁盘中永久删除连接配置文件。 nmcli c delete enp2s0-dhcp
常用配置参数列表(修改/新建时使用)

修饰前缀说明:

  • 直接赋值(如 ipv4.gateway 192.168.1.1):覆盖原有设置。
  • + 追加(如 +ipv4.addresses 192.168.2.100/24):追加一个新值(用于单网卡多 IP / 多路由)。
  • - 移除(如 -ipv4.routes "10.0.0.0/8 192.168.2.1"):删除指定的某一条配置。
  1. 基础与通用参数
参数名 语法 / 取值范围 说明
connection.id 自定义字符串 连接配置的名称(如 ens33
connection.interface-name 硬件网卡名 绑定的物理或虚拟网卡名称(如 ens33eth0
connection.autoconnect yes / no 开机是否自动激活连接(默认 yes
connection.type ethernet / bridge / bond 连接类型(以太网、网桥、聚合链路等)
  1. IPv4 网络参数 (ipv4.*)
参数名 语法 / 示例 说明
ipv4.method manual(静态)/ auto(DHCP)/ disabled IP 地址获取模式
ipv4.addresses IP/掩码(如 192.168.1.100/24 配置 IPv4 地址及子网掩码
ipv4.gateway IP 地址(如 192.168.1.1 配置默认网关
ipv4.dns IP 地址(如 114.114.114.114 8.8.8.8 配置 DNS 服务器(多个用空格分隔)
ipv4.dns-search 域名(如 example.com 配置 DNS 搜索域
ipv4.routes "网段/掩码 网关"(如 "10.0.0.0/8 192.168.2.1" 配置静态路由
ipv4.ignore-auto-dns yes / no 在 DHCP 模式下是否忽略自动获取的 DNS
直接修改网卡对应的配置文件

nmcli 命令自动创建配置文件,不需要学习里面的语法是怎么写的

-配置文件在 /etc/NetworkManager/system-connections

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
[root@lab ~]# ls /etc/NetworkManager/system-connections
ens160.nmconnection
[root@lab ~]# cat /etc/NetworkManager/system-connections/ens160.nmconnection
[connection]
id=ens160
uuid=b212c1ec-5275-3d63-81f6-007b3ca9ef5b
type=ethernet
autoconnect-priority=-999
interface-name=ens160
timestamp=1784258298

[ethernet]

[ipv4]
address1=10.0.0.100/24,1.1.1.1
dns=33.22.11.33;
method=manual

[ipv6]
addr-gen-mode=eui64
method=auto

[proxy]

配置文件路径:/etc/NetworkManager/system-connections/<接口名>.nmconnection

配置 Section (分组) 字段名称 典型取值示例 详细含义说明
[connection] type ethernet 网络接口类型(以太网)
id con-eth0 连接配置的逻辑名称 (Connection ID)
interface-name eth0 绑定的物理/虚拟网卡硬件接口名称
uuid a1b2c3d4-e5f6-... 标识该网络配置文件的唯一识别码
autoconnect true / false 开机或插拔网线时是否自动激活连接(对应旧版 ONBOOT
[ipv4] method manual / auto / disabled IPv4 配置模式(manual 为静态,auto 为 DHCP,disabled 为禁用)
address1 20.0.0.100/24,20.0.0.2 IP 地址、子网前缀和网关(格式为 IP/掩码前缀,网关
gateway 20.0.0.2 默认网关地址(亦可单独写在此字段中)
dns 223.5.5.5;114.114.114.114; DNS 服务器地址列表(必须用英文分号 ; 分隔
never-default false / true 是否禁止将此连接用作默认路由(false 表示作为默认路由,对应旧版 DEFROUTE=yes
[ipv6] method auto / manual / disabled IPv6 配置模式(自动获取、手动配置或禁用)
address1 2001:db8::1/64 静态 IPv6 地址及前缀长度
[ethernet] mac-address 00:11:22:33:44:55 绑定的网卡物理硬件 MAC 地址
mtu 1500 网卡最大传输单元 (MTU)

修改了配置文件后,需要以下操作使更改生效

  • 如果是 network 网络管理服务,修改网卡配置文件之后,直接重启 network 服务即可生效
    1
    systemctl restart network
  • 如果是 NetworkManager 网络服务,修改网卡配置文件之后,直接重启 NetworkManager 服务是不会生效的,有两种方式
    • 先重启 NetworkManager 服务,然后进行 up
      1
      2
      systemctl restart NetworkManager
      nmcli connection up xxxxx
    • reload 重新加载这个 connection,然后进行 up
      1
      2
      nmcli connection reload
      nmcli connection up xxxx

网络 bond 技术

常见的网络高可用技术有两个:

  • bond
  • team

teambond 作用是一样的,只不过现在比较主流的还是网络 bond

graph TD
    App[上层应用 / 操作系统] -->|发送/接收数据| Bond0[逻辑网卡 bond0 <br> IP: 192.168.1.100]
    
    subgraph Linux 内核 Bond 驱动
        Bond0
    end

    Bond0 -->|链路调度| Eth0[物理网卡 eth0]
    Bond0 -->|链路调度| Eth1[物理网卡 eth1]

    Eth0 -->|网线 1| SW1[交换机 A]
    Eth1 -->|网线 2| SW2[交换机 B]

    classDef primary fill:#e1f5fe,stroke:#0288d1,stroke-width:2px;
    classDef secondary fill:#fff3e0,stroke:#f57c00,stroke-width:2px;
    classDef switch fill:#e8f5e9,stroke:#388e3c,stroke-width:2px;
    
    class App,Bond0 primary;
    class Eth0,Eth1 secondary;
    class SW1,SW2 switch;

网络 bond 可以实现网络高可用或提高网络性能:通过不同的 bond 级别实现不同的功能

Bond 级别 Bond 名称 (常用别名) 工作原理与特点 对交换机的要求
0
(常用)
round-robin
(balance-rr)
按照设备顺序依次轮询传输数据包。提供负载均衡容错能力 交换机需要配置聚合
(Trunking / 静止聚合)
1
(常用)
active-backup 仅有一个活动设备处理数据,当主设备宕机时由备用设备接管。仅提供容错能力 交换机不需要配置
(最常用,跨交换机首选)
2 load-balancing (xor)
(balance-xor)
根据源/目的 MAC 地址的异或算法结果选择传输设备。提供负载均衡容错能力 交换机需要配置聚合
(Trunking / 静止聚合)
3 fault-tolerance (broadcast)
(broadcast)
在所有网口上广播传输所有数据。提供高容错能力 (浪费带宽)。 交换机需要配置聚合 (Trunking)
4
(常用)
lacp
(802.3ad)
创建动态聚合组,共享相同传输速度。提供负载均衡容错能力 需要交换机支持 802.3ad (LACP),并配置 Trunking
5 transmit load balancing
(balance-tlb)
仅对发送流量按负载均衡分配,由当前主网口接收流量。提供发送负载均衡容错能力 交换机不需要配置
6 adaptive load balancing
(balance-alb)
包含了 Mode 5 的特性,并通过 ARP 协商实现发送和接收双向的负载均衡与容错。 交换机不需要配置
  • 配置网络bond案例(采用主备模式)
graph LR
    subgraph 服务器
        Bond0[bond0<br>192.168.1.100]
        Eth0[eth0 <br> 主链路 Active]
        Eth1[eth1 <br> 备链路 Standby]
        Bond0 --> Eth0
        Bond0 -.-> Eth1
    end

    subgraph 交换机架构
        SW1[主交换机 A]
        SW2[备交换机 B]
    end

    Eth0 ===|数据流量 100%| SW1
    Eth1 -.-|空闲备用 0%| SW2

    linkStyle 0 stroke:#2e7d32,stroke-width:3px;
    linkStyle 1 stroke:#9e9e9e,stroke-width:1px,stroke-dasharray: 5 5;
    linkStyle 2 stroke:#2e7d32,stroke-width:3px;
    linkStyle 3 stroke:#9e9e9e,stroke-width:1px,stroke-dasharray: 5 5;
sequenceDiagram
    autonumber
    actor Client as 客户端
    participant Bond as 服务器 bond0
    participant Eth0 as 物理网卡 eth0 (主)
    participant Eth1 as 物理网卡 eth1 (备)
    participant SW as 交换机网络

    Note over Bond, Eth1: 阶段一:正常通信中
    Client->>Bond: 发送请求包
    Bond->>Eth0: 经主网卡转发
    Eth0->>SW: 抵达交换机

    Note over Eth0: 阶段二:线路出现故障 (网线被拔出 / 端口挂掉)
    Eth0 -x SW: 链路中断!
    Bond-->>Eth0: MII 链路检测到 Link Down

    Note over Bond, Eth1: 阶段三:自动化无缝切换
    Bond->>Eth1: 提升 eth1 为 Active 状态
    Bond->>SW: eth1 发送免费 ARP (Gratuitous ARP)<br>刷新交换机 MAC 地址表

    Note over Bond, Eth1: 阶段四:网络自动恢复
    Client->>Bond: 继续发送请求
    Bond->>Eth1: 经新主网卡转发
    Eth1->>SW: 抵达交换机(业务无感知中断)

实现的目的:访问bond1对应的IP地址,即使物理网卡发生了故障,依旧可以通过这个IP地址来访问

准备工作:

  • 准备两张物理网卡
  • 如果是VMware虚拟机的话,必须保证俩张物理网卡的网络模式都是一样的

配置步骤:

  1. 删除或者备份物理服务器的两张物理网卡的 connection 配置文件
  2. 创建虚拟网卡设备 bond1,指定对应的 connection 配置文件,类型是 bond``,connection 名字叫做 con-bond1bond 模式为 active-backup 主备模式
1
2
3
[root@rhel9 ~]# nmcli connection add type bond con-name con-bond1 ifname bond1 mode active-backup
Connection 'con-bond1' (acab76be-2e04-4ea0-9afc-334715441e50) successfully added.

  1. 将两张物理网卡加入到 bond1 中,作为 bond1 的子接口
1
2
3
4
5
[root@rhel9 ~]# nmcli connection add type bond-slave con-name bond1-eth0 ifname eth0 master bond1 
Connection 'bond1-eth0' (de3c5fa7-08b9-4ea0-aeac-0cd5d40ab02c) successfully added.
[root@rhel9 ~]# nmcli connection add type bond-slave con-name bond1-eth1 ifname eth1 master bond1
Connection 'bond1-eth1' (fa7eae73-7d77-4d6f-9277-1a1615a39ef9) successfully added.

  1. 修改虚拟网卡设备bond1的网络信息,要求IP地址是20.0.0.100/24,dns 223.5.55,网关 20.0.0.2
1
2
3
4
[root@rhel9 ~]# nmcli connection modify  con-bond1 ipv4.method manual ipv4.addresses 20.0.0.100/24 ipv4.dns 223.5.5.5 ipv4.gateway 20.0.0.2 autoconnect yes 
[root@rhel9 ~]# nmcli connection up con-bond1
Connection successfully activated (master waiting for slaves) (D-Bus active path: /org/freedesktop/NetworkManager/ActiveConnection/15)

  • 查看网络bond的状态
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
[root@rhel9 ~]# cat /proc/net/bonding/bond1 
Ethernet Channel Bonding Driver: v5.14.0-362.8.1.el9_3.x86_64

Bonding Mode: fault-tolerance (active-backup)
Primary Slave: None
Currently Active Slave: eth0
MII Status: up
MII Polling Interval (ms): 100
Up Delay (ms): 0
Down Delay (ms): 0
Peer Notification Delay (ms): 0

Slave Interface: eth0
MII Status: up
Speed: 10000 Mbps
Duplex: full
Link Failure Count: 0
Permanent HW addr: 00:0c:29:66:cf:0e
Slave queue ID: 0

Slave Interface: eth1
MII Status: up
Speed: 10000 Mbps
Duplex: full
Link Failure Count: 0
Permanent HW addr: 00:0c:29:66:cf:18
Slave queue ID: 0

虚拟化的网络模式

  • NAT 模式(VMnet8)
  • 仅主机模式(VMnet1)
  • 桥接模式(VMnet0)

NAT 模式

虚拟机借用宿主机的 IP 访问外网。
VMware 会构建一个独立的虚拟 NAT 设备和虚拟 DHCP 服务器,外界无法主动访问虚拟机,但虚拟机可以顺畅访问外网。

graph TD
    Internet((互联网 / 外部网络)) <--> Router[物理路由器 / 网关<br>192.168.1.1]
    
    subgraph 物理宿主机 Host
        Eth0[物理网卡 <br> IP: 192.168.1.100]
        VMnet8[虚拟网卡 VMnet8 <br> IP: 10.0.0.1 <br> 仅用于宿主机访问虚拟机]
        
        subgraph VMware 虚拟网络
            vNAT[虚拟 NAT 设备 <br> 网关: 10.0.0.2]
            vDHCP1[虚拟 DHCP 服务器]
            vSwitch1[虚拟交换机 VMnet8]
            
            vNAT <--> vSwitch1
            vDHCP1 -.- vSwitch1
        end
        
        subgraph 虚拟机内部
            VM1[虚拟机 A <br> IP: 10.0.0.128]
            VM2[虚拟机 B <br> IP: 10.0.0.129]
        end
        
        Eth0 <--> vNAT
        VM1 <--> vSwitch1
        VM2 <--> vSwitch1
    end

    Router <--> Eth0

    classDef host fill:#e3f2fd,stroke:#1565c0,stroke-width:2px;
    classDef vnet fill:#fff3e0,stroke:#e65100,stroke-width:2px;
    classDef vm fill:#e8f5e9,stroke:#2e7d32,stroke-width:2px;
    
    class Eth0,VMnet8 host;
    class vNAT,vDHCP1,vSwitch1 vnet;
    class VM1,VM2 vm;

仅主机模式

虚拟机组成一个封闭的私有局域网。
去掉了 NAT 路由转发功能,虚拟机之间、虚拟机与宿主机之间可以互通,但完全隔离外网。

graph TB
    Internet((互联网 / 外部网络)) <--> Router[物理路由器 / 网关<br>192.168.1.1]
    
    subgraph 物理宿主机 Host
        Eth0[物理网卡 <br> IP: 192.168.1.100]
        VMnet1[虚拟网卡 VMnet1 <br> IP: 20.0.0.1]
        
        subgraph 虚拟网络 VMnet1
            vDHCP2[虚拟 DHCP 服务器]
            vSwitch2[虚拟交换机]
            vDHCP2 -.- vSwitch2
        end
        
        subgraph 虚拟机区域
            VM3[虚拟机 A <br> 20.0.0.128]
            VM4[虚拟机 B <br> 20.0.0.129]
        end
        
        VMnet1 <--> vSwitch2
        vSwitch2 <--> VM3
        vSwitch2 <--> VM4
    end

    Router <--> Eth0

    classDef host fill:#e3f2fd,stroke:#1565c0,stroke-width:2px;
    classDef vnet fill:#fff3e0,stroke:#e65100,stroke-width:2px;
    classDef vm fill:#e8f5e9,stroke:#2e7d32,stroke-width:2px;
    
    class Eth0,VMnet1 host;
    class vDHCP2,vSwitch2 vnet;
    class VM3,VM4 vm;

桥接模式

虚拟机通过物理网卡直接“挂”在物理局域网中。
虚拟机与宿主机地位平等,拥有和宿主机同一网段的独立 IP 地址,可以直接被局域网内的其他物理设备访问。

graph TB
    Internet((互联网 / 外部网络)) <--> Router[物理路由器 / DHCP<br>192.168.1.1]
    
    Router <--> SW[物理交换机 / 路由器 LAN 口]
    PC2[局域网其他物理机<br>192.168.1.105] <--> SW

    subgraph 物理宿主机 Host
        Eth0[物理网卡 <br> IP: 192.168.1.100]
        vBridge[虚拟网桥 VMnet0]
        
        subgraph 虚拟机区域
            VM5[虚拟机 A <br> 192.168.1.101]
            VM6[虚拟机 B <br> 192.168.1.102]
        end
        
        Eth0 <--> vBridge
        vBridge <--> VM5
        vBridge <--> VM6
    end

    SW <--> Eth0
    PC2 <--同网段直接互访--> VM5

    classDef host fill:#e3f2fd,stroke:#1565c0,stroke-width:2px;
    classDef vnet fill:#fff3e0,stroke:#e65100,stroke-width:2px;
    classDef vm fill:#e8f5e9,stroke:#2e7d32,stroke-width:2px;

    class Eth0 host;
    class vBridge vnet;
    class VM5,VM6 vm;

在 KVM 配置桥接网络

flowchart TD
    Start([开始: 创建 KVM 桥接网络]) --> ConfirmNIC[1. 确认物理网卡名称<br/>例如: eth0]

    ConfirmNIC --> NM_1["2) 创建网桥及其 Connection (配置文件名: con-br0):<br/>nmcli con add type bridge con-name con-br0 ifname br0"]
    
    NM_1 --> NM_2["3) 创建网卡绑定 Connection (配置文件名: con-br0-slave):<br/>nmcli con add type bridge-slave con-name con-br0-slave ifname eth0 master br0"]
    
    NM_2 --> NM_3{"4) IP 配置方式?"}
    
    NM_3 -->|DHCP 动态获取| NM_DHCP["修改 con-br0 配置:<br/>nmcli con modify con-br0 ipv4.method auto"]
    NM_3 -->|Static 静态地址| NM_STATIC["修改 con-br0 配置:<br/>nmcli con modify con-br0 ipv4.addresses 192.168.1.100/24<br/>nmcli con modify con-br0 ipv4.gateway 192.168.1.1<br/>nmcli con modify con-br0 ipv4.dns '8.8.8.8'<br/>nmcli con modify con-br0 ipv4.method manual"]
    
    NM_DHCP --> NM_Apply["5) 停用原网卡配置,启用新网桥配置:<br/>nmcli con down eth0<br/>nmcli con up con-br0"]
    NM_STATIC --> NM_Apply

    NM_Apply --> KVM_Config["6) 内核生成 br0 设备,KVM 虚拟机引用 br0"]
    KVM_Config --> End([完成])
  1. 挂载对应的 ISO 镜像文件
  2. 在操作系统上挂载对应 ISO 到指定的目录中
    1
    mount /dev/sr0 /media
  3. 配置本地 YUM 仓库
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    [root@rhel9 ~]# rm -rf /etc/yum.repos.d/* 
    [root@rhel9 ~]# cat > /etc/yum.repos.d/dvd.repo <<EOF
    [BaseOS]
    name=BaseOS
    baseurl=file:///media/BaseOS
    gpgcheck=0
    enabled=1

    [AppStream]
    name=AppStream
    baseurl=file:///media/AppStream
    gpgcheck=0
    enabled=1
    EOF

    [root@rhel9 ~]# yum makecache
    Updating Subscription Management repositories.
    Unable to read consumer identity

    This system is not registered with an entitlement server. You can use subscription-manager to register.

    BaseOS 2.7 MB/s | 2.7 kB 00:00
    AppStream 3.1 MB/s | 3.2 kB 00:00
    Metadata cache created.
  4. 安装软件包组
    1
    2
    [root@rhel9 ~]# yum groupinstall "Virtualization Host" -y 
    [root@rhel9 ~]# yum install virt-manager -y
  5. 启动服务
    1
    [root@rhel9 ~]# systemctl start libvirtd.service 
  6. 创建桥接网络
    1. 创建一个虚拟网卡设备 br0
    2. br0 虚拟网卡设备和真实的物理网卡设备桥接(绑定)
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    [root@rhel9 ~]# nmcli connection add type bridge con-name con-br0 ifname br0 
    Connection 'con-br0' (9f684d56-27dd-4789-9895-0a26798697fa) successfully added.
    [root@rhel9 ~]# ifconfig
    br0: flags=4099<UP,BROADCAST,MULTICAST> mtu 1500
    ether fe:f3:53:43:24:4a txqueuelen 1000 (Ethernet)
    RX packets 0 bytes 0 (0.0 B)
    RX errors 0 dropped 0 overruns 0 frame 0
    TX packets 0 bytes 0 (0.0 B)
    TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0

    [root@rhel9 ~]# nmcli connection add type bridge-slave con-name br0-eth0 ifname eth0 master br0

主机名本地映射

所谓的本地映射 就是通过修改系统的本地 hosts 文件,达到本地解析。

1
2
3
[root@rhel9 ~]# cat /etc/hosts
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6

如果配置了本地hosts文件解析,也配置了DNS服务器做解析,本地hosts文件优先级更高。

网络服务端口

监听端口如果是1024以下的,则这个服务必须是 root 用户启动。1024以下监听端口我们称之为特权端口。
监听端口是1024以上的,这个服务可以是普通用户启动页可以是 root 用户启动。1024以上的监听端口我们称之为非特权端口。

查看网络服务监听端口的命令工具:

  • ss
  • netstat

是因为查询网络监听效率的问题。对于操作系统上,如果有大量的监听情况,用 ss 的性能远远超过 netstat

1
2
3
4
5
6
7
常用选项(ss 和 netstat 都可用):
-tunlp
-t 查看 tcp 监听端口
-u 查看 udp 监听端口
-n 显示端口号;不加 n 显示的是服务名,例如把 22 替换显示为 ssh
-l 显示监听中的端口
-p 显示进程信息

shell 脚本实践

shell 脚本编写规范

  1. 脚本文件的名称一定要.sh 结尾,目的是为了别人知道这就是一个shell脚本
  2. 脚本文件的第一行内容要写上声明,声明用什么解释器去执行这脚本的内容
    1
    #!/bin/bash
    1
    #!/usr/bin/python
  3. 脚本中每一个命令要写上注释,表示这个命令是干什么使用的,注释符号使用#
    单行注释:#
    多行注释:<<EOF 开头,EOF 结尾
    1
    2
    3
    4
    5
    6
    #!/bin/bash
    <<eof
    echo huawei123
    echo redhat456
    eof
    echo root
  4. 脚本内容一定要有缩进

执行脚本的方式

执行方式 示例命令 需要可执行权限 (+x)? 运行进程环境 脚本变量能否影响当前终端? 核心适用场景
使用相对路径或绝对路径直接执行 ./script.sh 子 Shell 生产环境、常规脚本部署
显式指定 Shell 解释器执行 bash script.sh 子 Shell 临时测试无权限脚本
使用 source. 命令执行 source script.sh 当前 Shell 加载环境变量、刷新配置
提交给后台或计划任务静默执行 nohup ./script.sh & 后台子 Shell 长时间运行的大任务/服务

位置参数

当在终端运行一个 Shell 脚本或者函数时,在命令后面跟上的那些参数,会按照“从左到右的位置顺序”自动赋值给一组预定义的参数(从 $1 开始,多位数的参数用 ${n} 表示)。这组参数就叫做位置参数。

1
2
3
4
5
6
7
8
9
[root@rhel9 opt]# cat useradd.sh
#!/bin/bash
useradd $1
echo $2 | passwd --stdin $1
[root@rhel9 opt]# ./useradd.sh lisi redhat

# 相当于执行的是
useradd lisi
echo redhat | passwd --stdin lisi

脚本结合 read 命令实现提示信息

read 命令,它的主要作用是从标准输入(通常是键盘输入,也可以是文件或管道)读取一行数据,并将其赋值给一个或多个变量。

  • -p 选项可以指定提示信息(Prompt),编写脚本时多用此选项用来提示用户输入信息。
  • -t 超时时间,单位是s,超过了这个时间就会跳过这条read命令
  • -s 隐藏输入,从键盘上输入的信息不会显示出来
1
2
3
4
[root@rhel9 opt]# read -p "Input username: " 
Input username: memeda
[root@rhel9 opt]# set | grep memeda
REPLY=memeda # 不指定变量名时,默认赋值给 REPLY
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
[root@rhel9 opt]# cat useradd.sh
#!/bin/bash
read -t 60 -p "输入要创建的用户名称:" Username
read -sp "输入$Username的密码:" Password

useradd $Username
echo $Password | passwd --stdin $Username

# 脚本内容结束,接下来试运行

[root@rhel9 opt]# ./useradd.sh
输入要创建的用户名称:zhangxiaolong
输入zhangxiaolong的密码:
Changing password for user zhangxiaolong.
passwd: all authentication tokens updated successfully.

exit 和退出码

程序执行后会携带一个退出码:

  • 0 代表成功,1-255 代表失败
  • Shell 程序的退出码储存在系统变量 $?
  • 通过 exit num 指定退出码是多少

在脚本中,exit 一般配套判断语句使用。一旦脚本碰到了 exit 指令,则退出整个脚本的执行

复合指令

符号 符号名称 执行逻辑 / 条件 示例代码 典型使用场景
; 分号 无条件顺序执行:无论前面的命令成功或失败,后面的命令都会依次执行。 cd /tmp ; ls -l 纯粹将多条独立命令写在同一行执行。
&& 逻辑与 (AND) 前面成功才执行:只有前一条命令执行成功(退出码为 0),才会执行下一条命令。 make && make install 存在依赖关系的链式操作(如编译无误后才安装)。
|| 逻辑或 (OR) 前面失败才执行:只有前一条命令执行失败(退出码非零),才会执行下一条命令。 id zhangsan &>/dev/null || useradd zhangsan 备用方案或兜底逻辑(如用户不存在则创建用户)。
! 逻辑非 颠覆后接命令或条件的执行结果状态码,相当于把后面的 && 变成 ||,反之亦然 ! ping -c 1 -W 2 baidu.com &>/dev/null && echo "当前网络已断开!" 如果 ping 不通,则发出提示
| 管道符 数据传递:将前一条命令的标准输出(stdout)作为后一条命令的标准输入(stdin) ps -ef | grep nginx 对数据进行多级过滤、处理或统计。
& 后台运行符 异步/后台执行:将前一条命令放入后台运行,终端无需等待其完成,立即执行下一条命令。 python3 script.py & 执行耗时长的后台任务、服务启动脚本。
() 子 Shell 嵌套 子 Shell 隔离执行:将括号内的命令组合在新的子 Shell 进程中按顺序执行,内部的环境变更不影响当前 Shell。 (cd /tmp && tar -czf logs.tar.gz *.log) 临时切换目录执行操作,避免污染当前终端的工作路径。
{} 命令块组合 当前 Shell 组合执行:在当前 Shell 环境中将内部命令当成整体执行。 { date; who; } > status.log 将多条命令的输出统一重定向打包输出到文件。

条件与判断

条件测试语句

条件测试语句是用来判断条件是否为真或者为假,通常会应用到 ifcases 判断语句中以及 while 循环、until 循环语句中。

  • 条件为真,返回值为0
  • 条件为假,返回值为非0
  1. 格式1:test 条件表达式 多用于在终端上临时测试
1
2
3
4
5
6
[root@rhel9 opt]# test 1 = 1 
[root@rhel9 opt]# echo $?
0
[root@rhel9 opt]# test 1 = 2
[root@rhel9 opt]# echo $?
1
  1. 格式2:[条件表达式] 多用于 shell 脚本
    [root@rhel9 opt]# [ 1 = 2 ]
    [root@rhel9 opt]# echo $?
    1
    [root@rhel9 opt]# [ 1 = 1 ]
    [root@rhel9 opt]# echo $?
    0

  2. 格式3:[[ 条件表达式 ]] 支持原生的逻辑与/或,支持通配符与正则匹配

1
2
3
[root@lab ~]# [[ 1 = 1 && 2 = 2 ]]         # && 表示需要同时满足才会输出 0
[root@lab ~]# echo $?
0

需要注意的是 = 比较的是字符串而不是数字大小。

运算符 含义 / 缩写记忆法 详细说明与检测条件 典型场景
-f File (常规文件) 判断路径存在且为常规文件 检查配置文件、日志文件或脚本是否存在(如 /etc/hosts
-d Directory (目录) 判断路径存在且为目录 检查备份目录、挂载点是否存在(如 /mnt/vdb
-e Exist (存在) 判断路径是否存在(不限类型) 泛用性存在判断(管它是文件还是目录)
-s Size (非空文件) 判断文件存在且大小大于 0 检查日志是否有产生内容、数据库导出是否成功
-r Readable (可读) 判断当前用户是否有读权限 检查关键文件(如 /etc/shadow)当前用户能否读取
-w Writable (可写) 判断当前用户是否有写权限 检查对日志目录或数据目录是否有写入权限
-x Xecutable (可执行) 判断当前用户是否有执行权限 检查准备调用的脚本/二进制文件是否有 +x 权限
-L Link (软链接) 判断路径是否存在且为符号链接 检查快捷方式、版本软链接(如 /etc/redhat-release

案例:如果 /opt/useradd.sh 脚本文件没有x权限,则赋予x权限,如果有x权限则不管

1
[ -x /opt/useradd.sh ] || chmod a+x /opt/useradd.sh 

案例:判断 /etc/passwd 文件是否存在,如果存在则备份文件到 /opt/passwd.bak

1
[root@rhel9 opt]# [ -e /etc/passwd ] && cp /etc/passwd /opt/passwd.bak 

数值比较运算符

数值比较含义 适用于
[ ][[ ]]
适用于
(( ))
字母英文全称 传统 [ ] 示例 双圆括号 (( )) 示例
(变量无需加 $
等于 -eq == Equal [ $a -eq $b ] (( a == b ))
不等于 -ne != Not Equal [ $a -ne $b ] (( a != b ))
大于 -gt > Greater Than [ $a -gt $b ] (( a > b ))
大于等于 -ge >= Greater or Equal [ $a -ge $b ] (( a >= b ))
小于 -lt < Less Than [ $a -lt $b ] (( a < b ))
小于等于 -le <= Less or Equal [ $a -le $b ] (( a <= b ))

案例:判断根文件系统使用情况是否超过了 90%,如果超过了则输出 硬盘空间不足

1
2
3
4
5
6
[root@rhel9 opt]# df -h / | grep -oP '\d+(?=%)'
95
[root@rhel9 opt]# [ $(df -h / | grep -oP '\d+(?=%)') -gt 90 ] && echo 硬盘空间不足!
硬盘空间不足!
[root@rhel9 opt]# echo $?
0

字符串比较运算符

运算符 缩写 / 含义 详细功能说明 示例
= / == Equal (相等) 检查两个字符串内容是否完全一致 [ "$a" = "$b" ]
!= Not Equal (不相等) 检查两个字符串内容是否不一致 [ "$a" != "$b" ]
-z Zero Length (为空) 检查字符串长度是否为 0(未赋值或为空串) [ -z "$str" ]
-n Non-zero Length (非空) 检查字符串长度是否大于 0(有内容) [ -n "$str" ]
< Less Than (字典序小) 检查左侧字符串按字典序是否小于右侧字符串 [ "$a" \< "$b" ] (需转义)
> Greater Than (字典序大) 检查左侧字符串按字典序是否大于右侧字符串 [ "$a" \> "$b" ] (需转义)
=~ Regular Expression (正则) 检查左侧字符串是否匹配右侧正则表达式 [[ "$ip" =~ ^[0-9]+ ]]
单括号 [ ] 不支持

布尔运算符

逻辑含义 用于 [ ] 用于 [[ ]] (( )) 或命令行 逻辑规则说明 示例
逻辑非 (NOT) ! ! 条件为真则变为假,条件为假则变为真 [ ! -d "/tmp/backup" ]
逻辑与 (AND) -a (And) && 左右两边条件必须同时为真,整体才为真 [ -f "$file" -a -r "$file" ]
[[ -f "$file" && -r "$file" ]]
逻辑或 (OR) -o (Or) || 左右两边条件只要有一个为真,整体即为真 [ $age -lt 18 -o $age -gt 60 ]
[[ $age -lt 18 || $age -gt 60 ]]

判断、循环与中断

判断语句

if 判断
  • 单分支结构:条件表达式返回值为0则执行 if 语句中的代码。如果返回值不为0则跳过。
1
2
3
4
5
if 条件表达式;then
命令1
命令2
...
fi

示例:判断文件是否存在

1
2
3
4
5
#!/bin/bash

if [ -f "/etc/passwd" ]; then
echo "配置文件存在。"
fi
  • 双分支结构:条件满足执行分支 A,不满足则执行分支 B。
1
2
3
4
5
6
7
if 条件表达式;then
满足条件执行的命令
...
else
不满足条件执行的命令
...
fi

示例:验证当前用户是否为root

1
2
3
4
5
6
7
8
9
#!/bin/bash

# 检查当前用户是否为 root(EUID 为 0)
if [ "$EUID" -eq 0 ]; then
echo "当前是 root 用户,可以继续。"
else
echo "错误:需要 root 权限才能运行!"
exit 1
fi
  • 多分支结构:用于排他性的多条件依次评估,只要遇到第一个成立的条件,后续分支全部忽略。
1
2
3
4
5
6
7
8
9
10
if 条件表达式1;then
满足条件1执行的命令
...
elif 条件表达式2;then
满足条件2执行的命令
...
...
else
以上条件都不满足执行的命令
fi

示例:判断分数区间

1
2
3
4
5
6
7
8
9
10
11
12
#!/bin/bash

read -p "请输入考试成绩: " score
if [ "$score" -ge 90 ]; then
echo "优秀"
elif [ "$score" -ge 70 ]; then
echo "良好"
elif [ "$score" -ge 60 ]; then
echo "及格"
else
echo "不及格"
fi
case 判断

当需要对同一个变量匹配多个固定值(如菜单选择、启动脚本的 start/stop/restart)时,case 比叠加多个 elif 更加清晰简洁。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
case $变量 in
值1)
命令1
;;
值2)
命令2
;;
值3)
命令3
;;
*)
变量不属于以上任何值时执行的命令
;;
esac

示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#!/bin/bash

read -p "请输入要执行的操作 [start|stop|status]: " action

case "$action" in
start)
echo "正在启动服务..."
;;
stop)
echo "正在停止服务..."
;;
status)
echo "正在查看状态..."
;;
*)
echo "错误:无效的操作命令!"
;;
esac

循环语句

for 循环
1
2
3
for 变量名 in 循环的值;do
循环体(循环执行的内容)
done

循环的值的多种表达方式:

语法类别 代码写法(for 语句部分) 核心机制 / 说明
显式列表 (你的示例) for users in user1 user2 user3; do 直接枚举:手动用空格隔开每个值。
大括号范围扩展 for users in user{1..3}; do 序列生成:使用 {开始..结束} 自动拼接连续的数字或字母。
命令替换(文本/文件) for users in user$(cat user_list.txt); do
(假设文件写入了这三行)
指令取值:用 $(command) 将命令的标准输出按空格/换行切分为循环项。

案例:测试当前主机所在网段的所有的IP地址是否可以通信

  • 可以通信的主机,将其ip地址以 <ip> ok 的方式进行输出到显示屏上,并且存放到 /opt/ip-ok 文件中;
  • 不可以通信的主机ip,将其ip地址以 <ip> error 的方式进行输出到显示屏上,并且存放到 /opt/ip-error 文件中。
1
2
3
4
5
6
7
8
9
10
11
#!/bin/bash

#测试当前主机所在网段的所有的IP地址是否可以通信
for ips in 172.10.0.{1..254};do
ping -c2 $ips &> /dev/null
if [ $? -eq 0 ];then
echo $ips ok | tee -a /opt/ip-ok
else
echo $ips error | tee -a /opt/ip-error
fi
done
while 循环

只要 while 指定的条件评估为“真”(Exit Status 为 0),就会一直重复执行循环体内的代码,直到条件变假(退出状态码非 0)或被手动中断为止。

1
2
3
while 条件表达式/命令;do
(返回值为0,结果都为真,则执行)循环体
done

案例:创建新用户,用户名存在时要求重新输入

1
2
3
4
5
6
7
#!/bin/bash

read -p "输入用户名: " Username
while id $Username &> /dev/null;do
read -p "用户名已存在,输入其它用户名: " Username
done
useradd $Username
until 循环

while :只要条件成立(真),就一直做;直到条件不成立(假)才停止;
until :只要条件不成立(假),就一直做;直到条件成立(真)才停止。

1
2
3
until 条件表达式/命令;do
(返回值为非0,结果都为假,则执行)循环体
done

案例:持续 ping 某服务器,一旦 ping 通(返回 0),条件变为“真”,立即跳出循环继续执行后续脚本。

1
2
3
4
5
6
7
#!/bin/bash

until ping -c 1 -W 1 192.168.1.100 &> /dev/null; do
echo "目标服务器未响应,等待 3 秒后重试..."
sleep 3
done
echo "✅ 目标服务器已正常响应,开始执行部署命令!"

中断语句

continue 跳过本次

当需要遍历一批对象,但想过滤掉其中某些不合规项时,使用 continue 跳过此次循环,进行下一次的循环。

1
2
3
4
5
6
7
8
9
10
#!/bin/bash

# 打印 1 到 5,但跳过数字 3
for i in {1..5}; do
if [ "$i" -eq 3 ]; then
echo "⚠️ 匹配到 3,跳过本次循环!"
continue # 👈 直接跳过后面的 echo,进入下一个数字 (i=4)
fi
echo "当前数字: $i"
done
break 中断循环

当目的已经达到(如找到了所需文件)或遇到不需要再继续的条件时,使用 break 跳出循环。

break 只会中断并跳出它所在的那一层(最内层)循环,外层的循环依然会继续正常执行。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
[root@rhel9 opt]# cat break.sh
#!/bin/bash
for i in user{1..3};do
for k in pass{1..3};do
if [ $k = 'pass2' ];then
break
fi
echo $i $k
done
done

[root@rhel9 opt]# ./break.sh
user1 pass1
user2 pass1
user3 pass1

计划任务

一次性计划任务 at

  • 查看计划任务
    1
    2
    3
    4
    5
    6
    #列出系统的所有at计划任务(root可以列出所有用户的,普通用户只能列出自己的)
    [root@rhel9 ~]# at -l
    1 Sun Mar 8 15:00:00 2026 a root
    2 Mon Mar 9 08:00:00 2026 a root
    # 查看编号为 2 的任务详细脚本(包含环境变量恢复逻辑与你的命令)
    [root@rhel9 ~]# at -c 2
  • 编辑计划任务
    • 交互式
      直接输入 at [时间] 后回车,系统会进入交互式提示符 at>。此时可以输入多行 Shell 命令,最后按键盘 Ctrl + D 结束并保存。
      1
      2
      3
      4
      5
      [root@lab ~]# at now + 10 minutes
      at> echo "开始系统日志备份..." >> /var/log/backup.log
      at> /usr/local/bin/backup_script.sh
      at> <EOT> # 此处按 Ctrl + D 保存退出
      job 3 at Thu Aug 13 21:52:00 2026
    • 非交互式
      每次定义了at任务,都会在 /var/spool/at/ 目录下生成对应的可执行文件,当时间到了那一刻,其实是执行了这个可执行文件。可以直接去编辑此文件。
  • 删除计划任务
    1
    2
    3
    at -d 5

    atrm 5
  • at 的黑白名单
    • 黑名单文件 /etc/at.deny:处于文件中的用户无法使用 at 工具
    • 白名单文件 /etc/at.allow:除了文件中的用户可以使用 at 工具,其他用户都不可以使用(root 除外)
      默认情况下系统只存在黑名单文件。
      如果同时存在黑白名单文件,则只有白名单文件有效,黑名单无效。

周期性计划任务 crontab

  • 定义 crontab 计划任务
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    [root@rhel9 ~]# crontab -e
    # 然后会自动打开 vim
    * * * * * command_to_execute
    │ │ │ │ │
    │ │ │ │ └─── 星期几 (0 - 7) [0 或 7 都代表星期日]
    │ │ │ └─────── 月份 (1 - 12)
    │ │ └─────────── 日/日期 (1 - 31)
    │ └─────────────── 小时 (0 - 23)
    └─────────────────── 分钟 (0 - 59)
    */x:表示每隔 x 个时间执行任务
    x,y:表示在 x 时间和 y 时间执行任务
    x-y:表示在 x 时间和 y 时间范围内执行
  • 查看计划任务
    1
    2
    3
    4
    [root@rhel9 ~]# crontab -l 
    59 23 * * * /bin/echo root
    [root@rhel9 ~]# crontab -l -u zhangsan # 查看特定用户的计划任务
    * * * * * echo zhangsan
    定义的计划任务实际上是一个文件,这个文件会存储到 /var/spool/cron 目录下,目录下会生成对应用户名的文件,表示这个文件中的计划任务是由这个用户执行的。
    1
    2
    3
    4
    [root@rhel9 ~]# ll /var/spool/cron/
    total 8
    -rw-------. 1 root root 46 Mar 8 10:21 root # root用户的计划任务
    -rw-------. 1 root root 24 Mar 8 10:19 zhangsan # zhangsan用户的计划任务
  • 删除计划任务
    1
    2
    [root@rhel9 cron]# crontab -r
    [root@rhel9 cron]# crontab -r -u lisi
  • crontab 日志位置:/var/log/cron
  • 黑白名单
    • /etc/cron.deny 黑名单文件:处于黑名单文件的用户无法使用 crontab 工具
    • /etc/cron.allow 白名单文件:只有处于白名单文件的用户才可以使用 crontab 工具,除此之外其他用户都无法使用(root 除外)
      如果同时存在黑白名单,则黑名单文件无效。

拓展:/etc/cron.* 下放置计划任务脚本

/etc 目录下有四个文件夹:cron.hourlycron.dailycron.weeklycron.monthly,将脚本放置在对应的文件夹中,就会对应时间定期执行脚本。

其中 etc/cron.hourly 下的脚本是由 /etc/cron.d/0hourly 每小时触发运行的:

1
2
3
4
5
6
[root@lab ~]# cat /etc/cron.d/0hourly
# Run the hourly jobs
SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=root
01 * * * * root run-parts /etc/cron.hourly

etc/cron.hourly 下默认有一个 0anacron 脚本,作用是每小时拉起 anacron,如果今天已经跑过了则跳过。

anacron 通过读取 /etc/anacrontab 配置文件,会每隔固定时间分别运行 cron.dailycron.weeklycron.monthly 下的所有脚本:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
[root@lab ~]# cat /etc/anacrontab
# /etc/anacrontab: configuration file for anacron

# See anacron(8) and anacrontab(5) for details.

SHELL=/bin/sh
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=root
# the maximal random delay added to the base delay of the jobs
RANDOM_DELAY=45
# the jobs will be started during the following hours only
START_HOURS_RANGE=3-22

#period in days delay in minutes job-identifier command
1 5 cron.daily nice run-parts /etc/cron.daily
7 25 cron.weekly nice run-parts /etc/cron.weekly
@monthly 45 cron.monthly nice run-parts /etc/cron.monthly

调用链图解:

flowchart TD
    A["crond 守护进程"] -->|每小时第 01 分钟| B["读取 /etc/cron.d/0hourly"]
    B --> C["执行<br> run-parts /etc/cron.hourly<br>即执行该目录下的所有脚本"]
    C --> D["运行 /etc/cron.hourly/0anacron"]
    D --> E["启动 anacron 程序"]
    E --> F["读取 /etc/anacrontab"]
    
    F --> G["触发并执行 /etc/cron.daily/ 下的所有脚本"]
    F --> H["触发并执行 /etc/cron.weekly/ 下的所有脚本"]
    F --> I["触发并执行 /etc/cron.monthly/ 下的所有脚本"]

Gemini 拓展

为什么要搞得这么复杂?直接让 crond 跑不好吗?

了解了调用链后,你可能会产生疑问:为什么不直接在 /etc/cron.d/ 下写 4 个文件(0hourly0daily0weekly0monthly)让 crond 直接跑?

这源于传统 crond 的一个致命缺陷:

  • ❌ 传统 crond 的死穴:如果把 cron.daily 设置在每天凌晨 02:00 运行,但如果这台机器是个人笔记本或桌面 PC,晚上 02:00 恰好关机休眠了。那么当第二天早上开机时,02:00 已经过去,今天的 daily 任务就被静默跳过了!如果机器一直晚上关机,日任务和周任务将永远无法执行。

为了解决这个问题,现代 Linux 引入了 anacron(Anachronistic Cron,意为“打破时间顺规的 Cron”):

  • anacron 的优势:它不依赖“在精确的某个时间点必须开机”。它靠文件记录上一次运行的时间戳。开机后只要 crond(通过 0hourly)唤醒了 anacronanacron 发现“昨天/上周的任务还没跑”,就会在开机几分钟后把漏掉的任务补跑一遍。

为什么 cron.hourly 不使用 anacron 补跑?

每小时任务(Hourly)“补跑”没有实际意义。

anacron 设计的核心哲学是:“补跑那些即使延迟几小时执行,依然有价值的任务”(比如每天日志切割、每周数据库索引优化)。
但对于按“小时”单位运行的任务,补跑往往是毫无意义甚至是有害的:

  • 时效性极强:每小时任务通常是做清理 /tmp 临时文件、收集上一小时 CPU 指标等极短周期的动作。

因此,错过就错过,直接等待下一个整点(下一小时的第 01 分钟)再次触发,才是每小时任务最合理的逻辑。

文件查找工具

文件查找工具 locate

locate特点:

  1. 根据关键字搜索(模糊查找),只要文件名称包含这个关键字就可以搜索到;
  2. 根据数据库索引文件搜索,如果数据库的索引文件不存在则无法使用,需要执行 updatedb 命令来更新数据库索引文件;
  3. locate 不是实时查询,有可能有的文件明明存在但是无法查询到,要么就等待自己更新数据库索引,要么手动执行 updatedb 命令更新;
  4. 所有查找工具共同的特点,查找的目录必须要有 rx 权限。

常用选项:

1
2
-i 忽略关键字的大小写
-nx 列出指定n行

文件查找工具 find

find特点:

  1. 实时查询文件,默认精确查询,也可以进行模糊查询(支持各种通配符);
  2. find 工具可以在查找到文件的基础之上执行二次命令操作(比如搜索系统上所有以 .swp 结尾的文件,然后去删除掉);
  3. find 支持各种条件查询(根据文件名称查询文件、根据文件的 inode 编号查询文件、根据文件的权限查询文件、根据文件的拥有人/拥有组身份查询文件、根据文件的时间戳查询文件、根据目录的层级来查询文件…);
  4. 所有查找工具共同的特点,查找的目录必须要有 rx 权限;
  5. find查询的时候是遍历查询,所以速度较慢。

查询条件

查询维度 匹配参数 语法示例 详细解释与说明
文件名 -name find . -name "*.log" 按文件名匹配(区分大小写),查找所有 .log 结尾的文件
-iname find . -iname "test.txt" 按文件名匹配(不区分大小写),可匹配 Test.txtTEST.TXT
文件类型 -type find . -type f 按类型查找:f (普通文件), d (目录), l (符号链接)
文件大小 -size find . -size +100M 查找大于 100MB 的文件(+大于,-小于,无符号为精准匹配)
-size 是根据向上取整后的文件大小搜索,因此4.5MB 的文件不能用 -5M 搜索到,而可以用 5M 搜索到
find . -size -1k 查找向上取整后小于 1KB 的文件(即空文件)
修改时间
(天数)
-mtime find . -mtime -7 查找 7 天以内被修改过内容的文件(-代表以内,+代表之前)
find . -mtime +30 查找 30 天以前被修改过内容的文件
修改时间
(分钟数)
-mmin find . -mmin -60 查找 60 分钟以内被修改过内容的文件
访问/状态 -atime / -ctime find . -atime -1 -atime 按访问/读取时间,-ctime 按状态改变(权限/属主)时间
文件权限 -perm MODE find . -perm 755 严格匹配权限为 755 (rwxr-xr-x) 的文件
-perm /MODE find . -perm /755 任何一类(u,g,o)对象的权限中只要能一位包含/重合即可
-perm -MODE find . -perm -644 匹配至少包含 644 权限的文件
所有者/组 -user / -group find /home -user www 查找所属用户为 www 的文件
find / -group admin 查找所属用户组为 admin 的文件
无属主文件 -nogroup / -nouser find / -nouser 查找没有合法所属用户的孤儿文件(例如用户被删除)
路径深度 -maxdepth find . -maxdepth 2 -name "*.sh" 限制搜索深度最大为 2 层(不会深入更深度的子目录)
-mindepth find . -mindepth 2 -name "*.sh" 限制搜索深度最小为 2 层(忽略所有深度小于 2 的文件和目录)
非空/空文件 -empty find . -type f -empty 查找内容为空的普通文件或空目录
逻辑组合 -a find . -size +50k -a -size -100k 使用 -a 表示逻辑“与”,查找大于 50k 小于 100k 的文件;两个条件之间不加连接选项的话默认是此项
-o find . -name "*.jpg" -o -name "*.png" 使用 -o 表示逻辑“或”,查找 jpg png
! -not find . -type f ! -name "*.tmp" 使用 ! 表示否定(非),查找所有不是 .tmp 的文件

二次处理

选项 / 参数 语法格式 核心作用与特点 示例命令 说明 / 场景
-print find <路径> <条件> -print 默认动作。将查找到的文件路径打印输出到标准输出(屏幕) find /etc -name "*.conf" -print 查看符合条件的文件路径(不写 -print 时系统也会默认执行)
-ls find <路径> <条件> -ls 列出查找到的文件的详细信息(格式类似于 ls -dils find /var/log -type f -mtime -1 -ls 查看最近1天内修改过的日志文件的权限、大小、修改时间等详细属性
-delete find <路径> <条件> -delete 直接删除查找到的文件或空目录(由 find 内部直接执行,效率比 rm 高) find /tmp -name "*.tmp" -delete 快速清理临时文件;注意:若目录不为空则无法删除,且不经过确认直接删除
-exec find <路径> <条件> -exec <命令> {} \; find 查找出的每个文件作为参数传给后续命令并直接执行 find . -type f -exec rm -rf {} \; 批量强制删除当前目录下查找到的所有普通文件,无确认提示
-ok find <路径> <条件> -ok <命令> {} \; 在执行后续命令前,对每个文件逐一询问提示(需输入 yn 确认) find /var/log -name "*.log" -ok rm -f {} \; 安全删除日志文件,每次删除前会要求确认,防止误删
{} 占位符(配合 -exec / -ok 代表前面 find 搜索到的每一个文件/目录路径 find /tmp -type f -exec cp {} /backup/ \; 把查找到的文件逐个复制到 /backup/ 目录下
\; 命令结束符(配合 -exec / -ok 表示 exec/ok 参数列表的终止(反斜杠用于转义分号,防止被 Shell 提前解析) find . -name "*.tmp" -exec chmod 644 {} \; 批量将 .tmp 文件的权限修改为 644
+ 批量传递结束符 将所有找到的文件一次性打包传给命令(效率比 \; 高,类似于 xargs find /data -type f -name "*.txt" -exec chown root:root {} + 一次性将所有 .txt 文件的属主属组修改为 root

网络客户端

curl 工具

选项 / 参数 语法格式 核心作用与特点 示例命令 说明 / 场景
基础请求 curl <URL> 获取指定 URL 的响应内容并直接输出到标准输出(终端) curl https://www.example.com 快速测试页面连通性或获取网页源代码
-o curl -o <文件名> <URL> 将下载的内容保存为指定的本地文件名 curl -o mypage.html https://www.example.com 自定义保存下载文件的名称
-O curl -O <URL> 将下载的内容保存为远程服务端的原文件名 curl -O https://www.example.com/file.zip 直接按照原文件名下载文件到当前目录
-v / --verbose curl -v <URL> 显示详细的请求与响应过程(包含 Header、DNS 解析、TLS 握手等) curl -v https://api.example.com 排查网络连接、请求头或 API 报错问题
-I / --head curl -I <URL> 仅发送 HEAD 请求,只获取响应头,不下载页面主体内容 curl -I https://www.example.com 快速检查服务状态码(如 200、301、404)及缓存状态
-H curl -H '<Header信息>' <URL> 自定义添加或重写 HTTP 请求头 curl -H "Content-Type: application/json" -d '{"id":1}' https://api.com 发送 JSON 接口请求或传递 Token 认证信息
-s curl -s <URL> 静默模式,不输出进度条和错误信息 curl -s https://api.example.com/status 编写 Shell 脚本提取 API 结果时屏蔽无关输出
-u curl -u <用户名:密码> <URL> 提供 HTTP 基础认证(Basic Authentication) 的账号密码 curl -u admin:secret https://example.com/protected 访问需要 Basic 身份验证的接口或网页
-x curl -x <代理协议://IP:端口> <URL> 指定请求通过 HTTP/HTTPS/SOCKS5 代理服务器 发送 curl -x http://127.0.0.1:7890 https://www.google.com 绕过网络限制或使用指定 IP 发起请求

wget 工具

选项 / 参数 语法格式 核心作用与特点 示例命令 说明 / 场景
基础下载 wget <URL> 直接下载指定 URL 的文件并保存到当前目录(默认保留原文件名) wget https://example.com/file.tar.gz 最基础的文件下载操作
-O wget -O <文件名> <URL> 将下载的内容保存为指定的本地文件名(支持路径) wget -O /tmp/pkg.zip https://example.com/file.zip 重命名文件或下载至指定目录下
-P / --directory-prefix wget -P <路径> <URL> 将文件直接下载保存到指定的目录 wget -P /opt/downloads https://example.com/file.zip 保持原文件名并批量存入特定目录
-b / --background wget -b <URL> 后台下载,并将输出日志写入到 wget-log 文件中 wget -b https://example.com/large-iso.iso 下载大文件时释放当前终端面板
-c / --continue wget -c <URL> 断点续传,继续下载之前中断或未完成的文件 wget -c https://example.com/large-iso.iso 网络不稳定中断后恢复下载,避免从头开始
-q / --quiet wget -q <URL> 静默模式,不打印任何下载进度和输出信息 wget -q https://example.com/script.sh 编写自动化脚本时屏蔽终端输出日志
--user / --password wget --user=<账号> --password=<密码> <URL> 针对需要 HTTP/FTP 认证的站点提供账号密码凭据 wget --user=admin --password=secret https://example.com/file.zip 访问受受限保护的下载资源

SSH 协议和工具

sequenceDiagram
    autonumber
    actor User as 用户 / 客户端
    participant Server as 远程服务器 (sshd)

    Note over User: 提前生成密钥对<br/>~/.ssh/id_ed25519 (私钥)<br/>~/.ssh/id_ed25519.pub (公钥)
    Note over Server: 提前配置<br/>已将客户端公钥写入<br/>~/.ssh/authorized_keys

    User->>Server: 1. 发起 SSH 连接请求 (传输用户名等信息)
    Server->>Server: 2. 检查 authorized_keys 文件,确认存在该用户的公钥
    Server->>Server: 3. 生成一个随机质询字符串 (Challenge / Random String)
    Server->>User: 4. 发送质询字符串 (明文)
    
    User->>User: 5. 用【本地私钥】对质询字符串进行签名 (私钥加密/计算)
    User->>Server: 6. 将签名结果发送给服务器
    
    Server->>Server: 7. 用【客户端公钥】对签名进行解密与验证
    
    alt 验证通过
        Server-->>User: 8. 确认身份无误,登录成功!<br/>(双方切换为对称加密传输日常命令)
    else 验证失败
        Server-->>User: 登录失败 (Permission denied)
    end

配置免密登录

步骤 执行命令 / 配置内容 说明 / 关键参数
1. 生成密钥对 ssh-keygen -t ed25519 -N "" ls -l ~/.ssh/id_ed25519* 能够看到私钥和 .pub 公钥文件
-N "" 表示密码为空,实现无人值守;建议优先选择 ed25519 算法(性能与安全性均优于 rsa)。
2. 推送公钥 ssh-copy-id remote-user@192.168.23.129 >首次执行需要输入一次目标受控节点用户的 SSH 登录密码。
终端提示 Number of key(s) added: 1 表示成功。
3. 验证 SSH 免密 ssh remote-user@192.168.23.129 直接进入受控节点终端,无需输入密码

SSH 配置文件

SSH 服务端核心配置文件位置: /etc/ssh/sshd_config

参数名称 可选值示例 核心作用与说明
Port 22, 1022, 2222 等任意未占用端口 指定 SSH 服务监听的网络端口。生产环境中常修改此项以减少恶意扫描
ListenAddress 0.0.0.0, ::, 192.168.1.100 指定 SSH 服务绑定的 IP 地址。若只想让内网访问,可绑定指定的内网 IP
PermitRootLogin prohibit-password / without-password, yes, no 是否允许 root 用户远程登录。生产环境通常建议设置为 no 以提升安全性
PasswordAuthentication yes, no 是否开启密码认证登录。如果全部改用密钥登录,可设置为 no 来禁用密码
PubkeyAuthentication yes, no 是否开启基于公钥/私钥对的身份验证功能
AuthorizedKeysFile .ssh/authorized_keys, .ssh/authorized_keys2 指定保存客户端允许登录的公钥文件的路径(相对于用户的家目录)
MaxAuthTries 6, 3, 5 单次连接尝试认证的最大失败次数。超过此次数连接将被强制断开
AllowUsers 语法:AllowUsers user1 user2@ip 登录白名单。默认未设置(允许所有合法用户),一旦配置则仅允许指定用户登录
DenyUsers 语法:DenyUsers user3 user4@ip 登录黑名单。默认未设置,指定的列表用户将被显式拒绝登录
UseDNS option-dependent (通常为 yes / auto), no 是否对连接的客户端 IP 进行 DNS 反向解析。生产环境中建议设为 no 以大幅加快连接速度

SSH 隧道

  • 本地端口转发(正向代理、访问其它内网)
sequenceDiagram
    autonumber
    actor Me as 我的电脑 (Local)
    participant Host1 as 云主机1(公网 1.1.1.1 / 内网 10.0.0.1)
    participant Host2 as 云主机2(内网 10.0.0.2)

    Note over Me,Host1: 步骤一:我的电脑主动发起,与云主机1建立 SSH 隧道
    Me->>Host1: 执行 ssh -NL 10022:10.0.0.2:22 user1@1.1.1.1
    Note over Me: 本地打开并监听 10022 端口

    Note over Me,Host2: 步骤二:登录云主机2
    Me->>Me: 执行 ssh -p 10022 user2@127.0.0.1
    Me->>Host1: 流量发往本地 10022 端口,<br>通过 SSH 隧道加密传输至云主机1
    Host1->>Host2: 云主机1代为将请求转发至内网 10.0.0.2:22
    Host2-->>Host1: 云主机2响应连接
    Host1-->>Me: 响应结果经 SSH 隧道原路返回给我的电脑
    Note over Me: 成功登录云主机2!
  • 远程端口转发(反向代理、内网穿透)
sequenceDiagram
    autonumber
    actor Me as 我的电脑 (Local)
    participant Host1 as 云主机1(公网 1.1.1.1 / 内网 10.0.0.1)
    participant Host2 as 云主机2(内网 10.0.0.2)

    Note over Host1: 步骤一:在云主机1上建立反向隧道
    Host1->>Host1: 执行 ssh -NR 20022:10.0.0.2:22 user1@127.0.0.1
    Note over Host1: 云主机1 监听 20022 端口

    Note over Me,Host2: 步骤二:我的电脑发起连接
    Me->>Host1: 1. 普通 SSH 登录云主机1 (ssh user1@1.1.1.1)
    Me->>Host1: 2. 在云主机1上执行 ssh -p 20022 user2@127.0.0.1
    Host1->>Host1: 流量进入 20022 端口,走反向隧道解包
    Host1->>Host2: 根据配置将流量转发至内网 10.0.0.2:22
    Host2-->>Host1: 云主机2响应连接
    Host1-->>Me: 将终端回显返回给我的电脑
    Note over Me: 成功登录云主机2!
  • 动态端口转发(科学上网)
    1
    2
    3
    4
    ssh -NfD <port> user@server_ip
    -N 不执行远程命令
    -f 后台运行
    -D <port> 本地socks5端口

跨系统文件传输

scp 工具

scp(Secure Copy Protocol)底层同样基于 SSH 协议 进行安全传输。但在现代 OpenSSH 版本中,更推荐使用传输性能更好、支持断点续传的 rsync 或 OpenSSH 官方替代工具 sftp

参数 / 选项 典型用法示例 作用与功能说明
基础语法 scp [选项] 源路径 目标路径 命令基本结构。路径格式为 user@host:/path/to/file
本地 → 远程 scp file.txt user@1.1.1.1:/home/user/ 从本地电脑上传单文件到远程服务器
远程 → 本地 scp user@1.1.1.1:/var/log/app.log ./ 从远程服务器下载单文件到本地当前目录
远程 → 远程 scp user1@host1:/path/a.txt user2@host2:/path/ 跨两台远程服务器直接传输文件(需通过本地进行中转)
-r scp -r local_dir/ user@host:/remote/dir/ 递归复制:用于传输整个目录及其子目录下的所有内容
-P (大写) scp -P 2222 local.txt user@host:/remote/ 指定端口:当远程 SSH 服务修改了默认端口(22)时使用
-C scp -C large_file.tar user@host:/remote/ 开启压缩:在传输过程中启用 gzip 压缩,可提升大文本传输速度,但消耗 CPU 性能
-v scp -v local.txt user@host:/remote/ 显示详细日志:输出调试信息,常用于排查连接或权限故障
-p (小写) scp -p local.txt user@host:/remote/ 保留属性:传输时保留原文件的修改时间、访问时间和权限模式

sftp 工具

sftp(Secure File Transfer Protocol / SSH File Transfer Protocol) 是基于 SSH 协议的安全交互式文件传输工具。
与传统的 FTP 不同,SFTP 的所有数据传输(包括账号密码、文件内容和传输指令)均通过 SSH 加密隧道完成,默认运行在 22 端口,无需在服务器端安装额外的 FTP 服务,只要开启了 SSH 就能直接使用。

1
sftp user@remote_ip

在 SFTP 连接建立后,终端会进入 sftp> 交互式命令行环境。
一般都是使用支持 sftp 协议的图形化的工具来实现文件上传和下载。

rsync 工具

rsync(Remote Sync) 是 Linux/Unix 下最强大的增量文件同步与传输工具。它同样基于 SSH 协议进行加密传输,但相比 scprsync 最大的优势在于增量传输(Delta-transfer)算法——只传输修改过的部分,极大地节省了网络带宽和传输时间,且原生支持断点续传。

参数 / 选项 典型用法示例 作用与功能说明
基础语法 rsync [选项] 源路径 目标路径 命令基本结构。路径格式为 user@host:/path/to/file
-a (archive) rsync -av src/ dst/ 归档模式:等价于 -rlptgoD,递归传输并保留权限、时间戳、所有者、符号链接等所有元数据
-v (verbose) rsync -av src/ dst/ 显示详细过程:输出传输文件列表和总结统计信息
-z (compress) rsync -avz src/ dst/ 传输压缩:在传输过程中对文件数据进行压缩,适合跨网络传输文本/代码等
-P / --progress rsync -avP src/ user@host:/dst/ 显示进度与断点续传:等价于 --progress --partial,实时显示进度条并保留未传完的临时文件
-e rsync -avz -e "ssh -p 2222" src/ user@host:/dst/ 指定远程 Shell 路径/端口:自定义 SSH 连接参数(如修改后的 SSH 端口或特定私钥)
--delete rsync -av --delete src/ user@host:/dst/ 镜像同步:删除目标目录中那些源目录已经不存在的文件(保持两端绝对一致,谨慎使用)
--exclude rsync -av --exclude="*.log" src/ dst/ 排除指定文件/目录:同步时跳过符合规则的文件或文件夹(支持通配符)
-n / --dry-run rsync -avn --delete src/ user@host:/dst/ 模拟执行(演练):只打印将要执行的操作,不实际修改或传输任何文件(非常适合配合 --delete 预览)

高级权限管理

umask

特殊权限

特殊权限名称 赋权命令
(新增+,减去-
八进制数值 作用于普通文件 作用于目录 符号表示形式 (ls -l)
SUID
(Set User ID)
chmod u+s <file> 4 临时提权:当普通用户运行该可执行文件时,会临时获得文件所有者(通常是 root)的身份和权限执行。
(例如 /usr/bin/passwd)
仅对二进制文件有效,对脚本文件无效。
无实际意义:作用于目录时通常不会产生特殊效果。 替代所有者可执行位 x
• 有执行权限显示为小写 s
• 无执行权限显示为大写 S
SGID
(Set Group ID)
chmod g+s <file> 2 组提权:当用户运行该可执行文件时,会临时获得文件所属组的身份和权限执行。
仅对二进制文件有效,对脚本文件无效。
权限继承/团队协作:任何人在该目录下创建的新文件或子目录,其所属组都会自动继承该目录的所属组,而非创建者的主组。 替代所属组可执行位 x
• 有执行权限显示为小写 s
• 无执行权限显示为大写 S
Sticky Bit
(粘滞位)
chmod o+t <file> 1 无实际意义:在早期 Unix 中用于驻留内存,在现代 Linux 中对文件已失效。 防止误删共享文件:所有人均可在该目录下创建文件并设置完全权限,但只有文件所有者或 root 用户才能删除/重命名自己的文件。
(例如公共临时目录 /tmp)
替代其他用户可执行位 x
• 有执行权限显示为小写 t
• 无执行权限显示为大写 T

ACL 权限

getfacl 查看 ALC 规则

命令 典型用法示例 作用与功能说明
getfacl getfacl /var/www/data 查看指定目录或文件的详细 ACL 规则
1
2
3
4
5
6
7
8
9
10
11
[root@rhel9 ~]# getfacl /opt/
getfacl: Removing leading '/' from absolute path names
# file: opt/ # 文件名称
# owner: root # 文件拥有人
# group: root # 文件拥有组
user::rwx # 文件拥有人的权限
user:zhangsan:rwx # 用户 ACL 权限,受 mask 限制
group::rwx # 文件拥有组的权限,受 mask 限制
group:user:rwx # 用户组 ACL 权限,受 mask 限制
mask::rwx # ACL 权限掩码,决定最终有效的 ACL 和组权限
other::r-x # 其他人的权限

setfacl 设置 ACL 规则

常用选项/规则 典型用法示例 作用与功能说明
-m (modify) setfacl -m u:zhangsan:rw file.txt 赋予用户权限:为指定用户 zhangsan 单独赋予 rw- 权限
setfacl -m g:devgroup:rwx file.txt 赋予用户组权限:为指定用户组 devgroup 单独赋予 rwx 权限
-x (remove) setfacl -x u:zhangsan file.txt 删除特定规则:移除指定用户 zhangsan 的单独 ACL 规则
-b (remove all) setfacl -b file.txt 清空所有 ACL:删除该文件上的所有 ACL 规则,恢复为传统权限
-k (remove default) setfacl -k /project/ 删除默认权限:移除目录上的 Default ACL 继承规则(不影响已有文件)
-R (recursive) setfacl -R -m u:lisi:rx /project/ 递归设置:对目录及其内部的所有子目录和文件递归生效
g: (group rule) setfacl -m g:devgroup:rwx file.txt 组规则标识:显式指定针对特定用户组(Group)设置 ACL 权限
m: (mask rule) setfacl -m m::r-- file.txt 掩码规则标识:显式设置/锁定 Mask 掩码,限制所有 ACL 实体和主组的最大有效权限
d: (default) setfacl -m d:u:wangwu:rwx /project/ 默认权限(继承):在该目录下未来新建的文件/子目录,自动继承该 ACL

权限优先级

flowchart TD
    Start([用户请求访问文件]) --> IsRoot[是 root 用户?]

    IsRoot -- 是 --> Allow([允许访问])
    IsRoot -- 否 --> IsOwner[是所有者 Owner?]

    IsOwner -- 是 --> OwnerCheck[Owner 有权限?]
    IsOwner -- 否 --> HasACLUser[有专属 ACL 用户规则?]

    HasACLUser -- 是 --> ACLUserCheck[ACL User & Mask 有权限?]
    HasACLUser -- 否 --> InGroup[属于文件组/ACL组?]

    InGroup -- 是 --> GroupCheck[组权限并集 & Mask 有权限?]
    InGroup -- 否 --> OtherCheck[Others 有权限?]

    %% 最终结果分流
    OwnerCheck -- 是 --> Allow
    OwnerCheck -- 否 --> Deny([拒绝访问])

    ACLUserCheck -- 是 --> Allow
    ACLUserCheck -- 否 --> Deny

    GroupCheck -- 是 --> Allow
    GroupCheck -- 否 --> Deny

    OtherCheck -- 是 --> Allow
    OtherCheck -- 否 --> Deny

    %% 样式
    style Allow fill:#d4edda,stroke:#28a745
    style Deny fill:#f8d7da,stroke:#dc3545

sudo

允许普通用户在不需要知道超级管理员(root)密码的前提下,以 root 或其他特定用户的身份临时执行命令。

sudo 用法

选项 示例命令 作用与功能说明
-u / --user sudo -u zhangsan ls /home/zhangsan 指定目标用户:以指定用户(而非默认的 root)身份运行命令
-g / --group sudo -g devgroup touch file.txt 指定目标组:以指定用户组的身份运行命令
-i / --login sudo -i 登录式 Shell:切换到 root 并完全加载其环境变量与家目录
-l / --list sudo -l 列出权限:查看当前用户在 sudoers 文件中被赋予的所有可执行命令权限
-k / --reset-timestamp sudo -k 重置凭证/清空缓存:下一次执行 sudo 时必须重新输入密码
-K / --remove-timestamp sudo -K 彻底移除凭证:彻底清除缓存戳,强制后续调用重新验证
-b / --background sudo -b apt update 后台运行:将输入的命令放在后台异步执行
-V / --version sudo -V 查看版本信息:显示 sudo 程序版本号及详细的编译配置参数

配置文件格式

sudo 的规则保存在

  • /etc/sudoers 主配置文件
  • /etc/sudoers.d 模块化扩展目录
常用选项 / 常用语法 示例配置或命令 作用与功能说明
标准授权语法 (规则模板) 用户 主机=(目标用户:目标用户组) 标记 命令 Sudoers 语法标准架构:定义“谁、在何地、以谁的身份、带何种标志、执行何命令”
增加单人/单组全权授权 zhangsan ALL=(ALL:ALL) ALL
%devgroup ALL=(ALL:ALL) ALL
增加全权规则:允许用户 zhangsan 或用户组 devgroup 在任意主机上切换为任意用户/组并执行所有命令
增加免密执行规则 (NOPASSWD) lisi ALL=(root) NOPASSWD: /usr/bin/systemctl restart nginx 增加免密规则:允许用户 lisi 免输入密码以 root 身份重启 Nginx 服务
限制/禁止特定命令 (!) wangwu ALL=(ALL) ALL, !/usr/bin/passwd root 细粒度剔除命令:允许用户 wangwu 执行绝大多数命令,但明确禁止修改 root 密码
多个用户授权 zhangsan,lisi,%devgroup ALL=(ALL) ALL 多用户/组:使用逗号分隔多个用户名或组,共享同一套主机和命令授权
多个主机名约束 zhangsan webserver1,webserver2,192.168.1.100=(ALL) ALL 多主机限制:限定该规则仅在指定的多个主机名或 IP 地址上生效
多个提权目标用户 zhangsan ALL=(appuser,www-data,root) ALL 多目标用户:允许 zhangsan 使用 sudo -u 切换为列表中的任意特定用户执行命令
多个特定命令列表 zhangsan ALL=(root) /usr/bin/systemctl restart nginx, /usr/bin/systemctl reload nginx, /usr/bin/tail -f /var/log/nginx/* 多命令限定:使用逗号分隔多个允许执行的绝对路径命令
定义别名组 (Alias) User_Alias WEBDEV = zhangsan, lisi
Host_Alias WEBHOSTS = web1, web2
Runas_Alias WEBOP = www-data, appuser
Cmnd_Alias WEB_CMD = /usr/bin/systemctl restart nginx, /usr/bin/systemctl reload nginx
WEBDEV WEBHOSTS=(WEBOP) NOPASSWD: WEB_CMD
批量组合管理:通过定义用户别名 (User_Alias)、主机别名 (Host_Alias)、目标用户别名 (Runas_Alias) 和命令别名 (Cmnd_Alias) 实现高效、集中的复杂规则配置
删除授权规则 在文件内部直接删除/注释对应配置行,或删除扩展文件:
sudo rm /etc/sudoers.d/webdev
删除规则:直接删除或注释掉配置整行;若在 .d 目录中,直接清除对应的子配置文件即可

visudo 安全编辑配置文件

使用 visudo 命令编辑规则文件,会在保存前检查语法,避免语法错误导致所有 sudo 告瘫。

常用选项 / 常用语法 示例配置或命令 作用与功能说明
visudo 默认编辑 /etc/sudoers
-c (check) visudo -c 纯语法检查:仅检查当前 /etc/sudoers 及其 .d 目录文件是否存在语法错误,不进行编辑
-f (file) visudo -f /etc/sudoers.d/devuser 编辑指定文件:安全地编辑 /etc/sudoers.d/ 目录下的子配置文件,不存在则新建
-q (quiet) visudo -c -q 静默检查:配合 -c 使用,只有在发现语法错误时才打印报错信息(常用于自动化脚本)
-V (version) visudo -V 查看版本:输出 visudo 工具的版本及参数信息

深入理解文件系统

块设备

块设备类型 典型设备名称 / 命名规则 说明与应用场景
SATA / SAS / SCSI 硬盘 & SSD /dev/sda, /dev/sdb 传统及标准硬盘:按照识别顺序依次分配字母(如第一块盘为 sda,分区表示为 sda1, sda2
NVMe 高速固态硬盘 /dev/nvme0n1, /dev/nvme1n1 PCIe 协议固态硬盘:格式为 nvme[控制器号]n[命名空间号],其分区表示为 /dev/nvme0n1p1
MMC / SD 卡 /dev/mmcblk0, /dev/mmcblk1 嵌入式存储 / SD卡:多用于树莓派、移动设备或存储卡,其分区表示为 /dev/mmcblk0p1
VirtIO 虚拟化块设备 /dev/vda, /dev/vdb KVM / QEMU 虚拟机:Linux 虚拟化环境下的半虚拟化高性能磁盘,分区表示为 vda1
Xen 虚拟化块设备 /dev/xvda, /dev/xvdb Xen 架构虚拟机:如 AWS EC2 实例中常见的虚拟磁盘名称,分区表示为 xvda1
LVM 逻辑卷 /dev/mapper/vg0-lv0
/dev/vg0/lv0
逻辑卷管理:映射在 /dev/mapper//dev/卷组名/逻辑卷名 下的虚拟块设备
MD RAID 阵列 /dev/md0, /dev/md1 软 RAID 磁盘阵列:通过 mdadm 工具创建并管理的软件磁盘阵列设备
光盘驱动器 (CD/DVD) /dev/sr0 (或 /dev/cdrom) SCSI 光盘驱动器cdrom 通常是指向 sr0 的符号链接
IDE / ATA 硬盘 (旧式) /dev/hda, /dev/hdb 老旧并行接口硬盘:主盘为 hda,从盘为 hdb(现代 Linux 内核大多已统一统一映射为 sd*

文件系统的概念

VFS(Virtual File System,虚拟文件系统) 是 Linux 内核中的一个抽象软件层。

它的核心作用是在各种不同的具体文件系统(如 ext4、xfs、btrfs、fat32、NFS 等)之上提供统一的接口。

有了 VFS,用户和应用程序完全不需要关心底层的磁盘格式或文件系统差异,只需要调用通用的系统函数(如 open()、read()、write()、close()),就能读写任意介质上的数据。

graph TD
    %% 1. 物理层 (Physical Layer)
    subgraph Layer1["1. 物理硬件层 (Physical Hardware)"]
        HD1["物理硬盘 1<br/>(HDD / NVMe)"]
        HD2["物理硬盘 2<br/>(HDD / NVMe)"]
    end

    %% 2. 块设备与软件阵列层 (Block Device & RAID)
    subgraph Layer2["2. 块设备与阵列层 (Block Device & RAID)"]
        BD1["基础块设备<br/>(/dev/sda)"]
        BD2["基础块设备<br/>(/dev/sdb)"]
        RAID["MD RAID 软阵列<br/>(/dev/md0)"]
    end

    %% 3. 磁盘分区层 (Partitioning)
    subgraph Layer3["3. 磁盘分区层 (Partitioning)"]
        P1["物理分区<br/>(/dev/sda1)"]
        P2["物理分区<br/>(/dev/sda2)"]
        P_RAID["阵列分区<br/>(/dev/md0p1)"]
    end

    %% 4. LVM 逻辑卷层 (LVM)
    subgraph Layer4["4. 高级逻辑卷层 (LVM)"]
        PV["物理卷 (PV)"]
        VG["卷组 (VG)"]
        LV["逻辑卷 (LV)<br/>(/dev/mapper/vg0-lv0)"]
    end

    %% 5. 文件系统格式化层 (File System)
    subgraph Layer5["5. 文件系统格式化 (File System)"]
        FS1["ext4 文件系统"]
        FS2["xfs 文件系统"]
    end

    %% 6. VFS 与 挂载点 (VFS & Mount Point)
    subgraph Layer6["6. 系统目录结构 (VFS & Directory Tree)"]
        VFS["虚拟文件系统 (VFS)"]
        MP1["挂载点 /boot"]
        MP2["挂载点 /data"]
    end

    %% 关系连接与完整操作命令
    HD1 --> BD1
    HD2 --> BD2

    %% 路径 A: 块设备 -> 分区
    BD1 -->|"fdisk /dev/sda 或<br> parted /dev/sda"| P1
    BD1 -->|"fdisk /dev/sda 或<br> parted /dev/sda"| P2

    %% 路径 B: 多块设备 -> RAID
    BD1 -->|"mdadm --create /dev/md0 --level=1 --raid-devices=2 /dev/sda /dev/sdb"| RAID
    BD2 -->|"mdadm --create /dev/md0 --level=1 --raid-devices=2 /dev/sda /dev/sdb"| RAID
    RAID -->|"fdisk /dev/md0"| P_RAID

    %% 路径 C: 分区/阵列 -> LVM
    P2 -->|"pvcreate /dev/sda2"| PV
    P_RAID -->|"pvcreate /dev/md0p1"| PV
    PV -->|"vgcreate vg0 /dev/sda2 /dev/md0p1"| VG
    VG -->|"lvcreate -L 100G -n lv0 vg0"| LV

    %% 格式化命令 (mkfs)
    P1 -->|"mkfs.ext4 /dev/sda1"| FS1
    LV -->|"mkfs.xfs /dev/mapper/vg0-lv0"| FS2

    %% 挂载命令 (mount / /etc/fstab)
    FS1 -->|"mount /dev/sda1 /boot"| MP1
    FS2 -->|"mount /dev/mapper/vg0-lv0 /data"| MP2

    MP1 --> VFS
    MP2 --> VFS

    %% 样式调整
    style Layer1 fill:#f9f9f9,stroke:#333,stroke-width:1px
    style Layer2 fill:#e1f5fe,stroke:#0288d1,stroke-width:1px
    style Layer3 fill:#fff3e0,stroke:#f57c00,stroke-width:1px
    style Layer4 fill:#f3e5f5,stroke:#7b1fa2,stroke-width:1px
    style Layer5 fill:#e8f5e9,stroke:#388e3c,stroke-width:1px
    style Layer6 fill:#ffebee,stroke:#d32f2f,stroke-width:1px

文件系统分类

操作系统 / 架构类型 主流文件系统 核心特点与优势 主要应用场景与局限性
Linux ext4 成熟稳定:Linux 长期默认的经典文件系统,具备日志功能(Journaling),兼顾兼容性与性能 大多数常规 Linux 发行版(如 Ubuntu、Debian)的默认根文件系统
XFS 高并发与大文件:采用分配组架构,在大文件读写、并行 I/O 及超大容量扩展上表现极为出色 企业级 Linux 发行版(如 RHEL、Rocky Linux)的默认文件系统,常用于数据库及大数据存储
Btrfs 高级写时复制(CoW):内置 RAID 支持、秒级快照、动态卷管理以及数据校验和防静默损坏 个人桌面发行版(如 Fedora、openSUSE)及大部分 NAS 系统(如群晖 DSM)
ZFS 终极存储管理:集文件系统与逻辑卷管理于一体,提供极强的 CoW 快照、数据自愈能力及高性能缓存逻辑 高可用存储服务器、Proxmox VE (PVE) 虚拟化平台、FreeBSD 系统
Windows NTFS 功能全面:支持细粒度 ACL 访问控制、透明压缩、加密(EFS)、日志及卷影复制(VSS) Windows 操作系统安装盘(C盘)及大部分 Windows 环境下的内置硬盘分区
exFAT 跨平台轻量:专为闪存设计,去除日志机制以减少写入磨损,单文件支持突破 4GB 限制 U 盘、SD 卡、移动硬盘等需要在 Windows、macOS 及 Linux 之间跨平台交换数据的设备
FAT32 极高兼容性:几乎被所有已知电子设备原生支持(包括嵌入式设备、路由器) 小容量 U 盘、SD 卡及 UEFI 系统引导分区(ESP)。局限:单文件最大仅支持 4GB
网络文件系统 NFS (v3/v4) Linux/Unix 原生:基于 RPC 协议,开销小、传输效率极高,原生保留 Linux 用户权限与属性 Linux 服务器集群间的数据共享、Kubernetes/PVE 等虚拟化平台的共享存储底座
SMB / CIFS 跨平台通用:微软开发的网络共享协议(Samba 实现),支持 Windows 域控(AD)权限管理 局域网文件共享、NAS 对外挂载共享目录(支持 Windows、macOS、Linux 及移动端同时访问)
WebDAV HTTP/HTTPS 透传:基于 Web 协议扩展,天然具备穿透防火墙能力,支持 SSL 加密 跨网段/公网远程挂载私有云(如 Nextcloud)、网盘挂载及跨平台文档同步
光盘文件系统 (Optical) ISO 9660 只读光盘标准:跨平台通用的只读文件系统格式,包含 Rock Ridge(扩展 Linux 属性)与 Joliet(扩展 Unicode 长文件名)规范 CD-ROM、DVD-ROM 标准光盘镜像(如系统安装盘 .iso 文件)
UDF 通用磁盘格式:专为可读写光盘与高密度介质设计,支持大文件写入、可追加刻录与更灵活的元数据 DVD 视频光盘、蓝光光盘(BD-ROM/BD-R)及大容量可擦写光盘
分布式文件系统 (Distributed) CephFS 去中心化无单点故障:基于 RADOS 算法,提供统一的 POSIX 文件系统接口,支持自动平衡、高扩展与强一致性 超融合架构(如 PVE/OpenStack 存储池)、大型云计算数据中心共享存储
GlusterFS 无元数据节点架构:基于哈希算法(DHT)计算数据位置,部署简单、扩展方便,支持跨机房镜像 大文件连续读写、云存储备份、日志存档及中间件共享文件存储
HDFS 大数据批处理:采用主从(NameNode/DataNode)架构,针对高吞吐的大文件一次写入、多次读取(WORM)进行优化 Hadoop 生态圈、大数据分析及数据仓库底座
JuiceFS 云原生分层存储:将元数据存储在 Redis/MySQL 等数据库中,数据持久化到对象存储(OSS/S3),支持 POSIX 接口 AI 训练数据集共享、K8s 容器持久化卷(PV)、跨云数据同步

文件数据的组成

文件类型 元数据 (Inode) 数据块 (Data Block)
普通文件 • 文件类型与权限位(- / rwxr-xr-x / SUID / SGID)
• 所有者信息(uid / gid
• 文件大小与占用块数(i_size / i_blocks
• 硬链接计数(i_nlink
• 时间戳(atime / mtime / ctime
• 数据块指针 / Extent 索引树节点
• 文本 / 二进制文件数据
• 原始字节流
目录文件 • 文件类型与权限位(d / rwxr-xr-x
• 所有者信息(uid / gid
• 目录项列表本身大小(i_size
• 硬链接计数(i_nlink
• 时间戳(atime / mtime / ctime
• 数据块指针
• 目录项结构体数组(Dentry List):
  – 下属文件 Inode 编号(inode
  – 下属文件名(name
  – 下属文件名长度(name_len
  – 下属文件类型标志(file_type

文件操作对 inode 的影响

操作指令 / 链接类型 Inode 编号变化 数据块 (Data Block) 变化 目录项 (Dentry) 变化 核心底层逻辑说明
rm (删除文件) 不变 (直到链接数清零) 不变 (直接释放) 擦除映射 擦除上级目录中的文件名与 Inode 映射,并将 Inode 的硬链接计数 (i_nlink) 减 1。当链接数归零且无进程占用时,位图会将对应 Inode 和 Data Block 标记为“空闲”(数据仍保留在磁盘上直至被覆盖)。
mv (同分区移动/重命名) 保持不变 完全不变 更新映射 数据和 Inode 均不做物理搬移。仅在旧目录中删除映射、在新目录中新建指向相同 Inode 的映射。因此同分区改名或移动几乎秒级完成。
mv (跨分区移动) 分配新 Inode (原 Inode 释放) 重新写入新 Block 新增并删除 不同分区的 Inode 编号不互通,底层本质上是先在目标分区 cp,再在源分区 rm。目标文件会生成全新的 Inode 编号。
cp (复制文件) 分配新 Inode 分配新 Block 新建映射 建立全新的独立文件。操作系统在目标位置分配新 Inode 复制元数据,分配新 Data Block 拷贝内容,并在目标目录建立新映射。
硬链接 (ln src dst) 共享原 Inode 共享原 Block 新建映射 不会创建新文件。仅在目标目录新建一个文件名,并将其指向源文件的同一个 Inode,同时将该 Inode 的硬链接计数加 1。删掉源文件不影响硬链接的访问。(局限:不能跨分区,不能对目录创建)
软链接 (ln -s src dst) 分配新 Inode 分配新 Block 新建映射 建立一个全新的特殊文件。分配独立的 Inode 和 Data Block,其数据块内专门存储目标文件的路径字符串(类似于 Windows 的快捷方式)。如果源文件被删,软链接就会变成悬空失效状态。(优势:支持跨分区、支持对目录创建)

du df 查看磁盘空间

维度 / 命令 du (Disk Usage) df (Disk Free) 两者核心对比 / 关联
核心定位与视角 文件视角:递归遍历目录与文件,累加空间 分区视角:直接读取文件系统元数据(位图/超级块) 作用侧重df 看整体剩余,du 找占用源头
常用语法 du [选项] [目录/文件] df [选项] [路径] -
易读单位 (Human) du -h [目录] df -h -h 均为最常用选项:自动转换容量单位为 K、M、G
汇总 / 全局 du -sh [目录] (仅输出指定目录总大小) df -h (默认展示所有挂载分区的总体情况) du 默认展开所有子目录,需加 -s 汇总;df 默认直接输出全局汇总
定位大文件 / 细节 du -h --max-depth=1 [目录] (仅展示第1级子目录大小) df -hT (额外输出文件系统类型如 ext4/xfs)
df -hi (查看 Inode 数量与使用率)
du 适合在特定文件夹内深度定位大目录/文件;df 适合确认分区类型与 Inode 是否耗尽
执行速度 较慢(需深度遍历树状目录与所有文件) 极快(仅读取索引表,瞬间完成) 磁盘文件极多时慎用无限制的 du /
单文件统计差异 计算“磁盘实际占用的 Block 块”
例如:1 字节的空文件在 4KB 块大小的磁盘上,du 会显示占用 4KB
计算“文件本身的真实逻辑字节数”
例如:1 字节的文件,ls -l / df 逻辑视角显示 1 Byte
机制差异du 按物理 Block 向上取整计算(包含文件系统分配对齐的空间);df 统计单个文件路径时展示的是逻辑尺寸
空间不一致原因 不统计“已删除但进程仍持有的文件” 依然计入“已删除但句柄未释放的文件” df 显示满但 du 找不到大文件时,执行 lsof | grep deleted 排查未释放句柄

文件系统查看、制作、挂载

步骤 / 阶段 核心作用与底层逻辑 典型具体命令示例 常用选项及作用说明 注意事项 / 提示
步骤 1:查看与识别
(lsblk)
检测与确认设备
列出系统中的所有块设备,确认新硬盘的设备名称(如 /dev/sdb/dev/nvme0n1p1),避免误操作其他已有数据的磁盘
lsblk -f -f:显示文件系统类型(FSTYPE)、UUID 和挂载点
-l:以平铺列表形式输出(便于脚本处理)
必须仔细核对磁盘名称与容量,防止后续误格式化系统盘或数据盘
步骤 2:创建文件系统
(mkfs)
初始化磁盘元数据
在物理磁盘或分区上写入文件系统的底层结构(如分配 Inode 表、Block 块大小、超级块等),即“格式化”
mkfs -t ext4 /dev/sdb1

mkfs.ext4 /dev/sdb1
-t <格式>:指定文件系统类型(如 ext4xfs
-b <大小>:指定 Block 块大小(如 -b 4096 指定 4KB 块)
高危破坏性操作:会清空设备上的全部已有数据!操作前务必二次确认设备路径
步骤 3:临时挂载测试
(mount)
将存储接入文件树
将已初始化文件系统的块设备与系统的某个空目录(挂载点)关联,使用户和程序可以通过路径访问磁盘存储
mount -t ext4 /dev/sdb1 /mnt/data -t <类型>:显式指定文件系统格式
-o ro:指定挂载权限(只读 ro / 可读写 rw
-o remount:不解除挂载的情况下动态更新挂载参数
--bind:将一个已有的目录映射挂载到另一个目录
挂载点目录建议是空目录;若目录下原有文件,挂载后原有文件会被隐蔽(解除挂载后恢复)
步骤 4:配置开机持久化
(/etc/fstab)
实现重启后自动挂载
将设备 UUID 和挂载参数写入 /etc/fstab
vi /etc/fstab fstab 格式:<UUID> <挂载点> <类型> <参数> <dump> <pass> 修改后必须使用 mount -a 校验!若 /etc/fstab 配置存在语法错误且未验证,重启系统会导致开机卡死(进入 Single User 救援模式)
步骤 5:自动挂载与校验
(mount -a)
模拟开机加载并验证
强制系统立即读取 /etc/fstab 文件中配置的所有尚未挂载的分区,用于验证配置文件语法是否正确
mount -a -a:挂载 /etc/fstab 中所有未挂载的文件系统
-v:输出详细的挂载过程信息(用于排错)
-t <类型>:仅挂载 fstab 中指定类型的记录
修改 fstab 后必须立刻执行!若配置有误且未经 mount -a 校验,重启系统会导致开机卡死并进入救援模式

tar 文件打包与压缩

  • tar 命令介绍
参数选项 全称 / 对应英文 核心作用与意义 示例说明
-c create 创建新的归档文件(打包) tar -cf demo.tar /data (将 /data 打包)
-x extract 提取 / 解压归档文件 tar -xf demo.tar (解压文件到当前目录)
-t list 列出归档文件内部的清单,不进行真实解压 tar -tvf demo.tar (预览里面有哪些文件)
-v verbose 显示详细过程,在终端打印正在处理的文件列表 tar -cvf demo.tar /data (屏幕会滚动显示被打包的文件名)
-f file 指定目标文件名必须紧跟在后,后接文件名 tar -cf demo.tar-f 后面必须紧跟 demo.tar
-z gzip 调用 gzip 压缩/解压算法(后缀 .tar.gz.tgz(常用) tar -zcf demo.tar.gz /data
-j bzip2 调用 bzip2 压缩/解压算法(后缀 .tar.bz2 tar -jcf demo.tar.bz2 /data
-J XZ (大写) 调用 xz 压缩/解压算法(后缀 .tar.xz tar -Jcf demo.tar.xz /data
-C Change directory (大写) 指定解压的目标路径(避免全部解压到当前目录) tar -zxf demo.tar.gz -C /opt/ (解压到 /opt/
-p preserve permissions 保留文件原始权限与属性(如所有者、读写执行权限等) tar -zcpf backup.tar.gz /var/www (常用于系统备份)
--exclude exclude 排除指定的文件或目录不参与打包 tar --exclude="*.log" -zcf app.tgz /app (打包时跳过 .log
  • 各压缩格式介绍
压缩格式 / 后缀 核心压缩算法 常见打包 / 压缩命令示例 常见解压命令示例 特点及适用场景
.tar 无压缩 (仅打包/归档) tar -cf archive.tar /path tar -xf archive.tar 将多个文件或目录整合为一个单独的文件,不减小体积。作为 Linux 体系下绝大多数压缩格式的基础
.tar.gz / .tgz gzip (DEFLATE 算法) tar -zcf archive.tar.gz /path tar -xf archive.tar.gz
(自动识别格式)
Linux 最通用格式。压缩/解压速度极快,CPU 占用低,压缩率适中,完美兼容绝大多数 Unix/Linux 系统
.tar.bz2 bzip2 (Burrows-Wheeler) tar -jcf archive.tar.bz2 /path tar -xf archive.tar.bz2
(自动识别格式)
压缩率高于 .tar.gz,但压缩/解压消耗的 CPU 时间和资源更多。适合对空间敏感但对速度要求较低的归档
.tar.xz xz (LZMA2 算法) tar -Jcf archive.tar.xz /path tar -xf archive.tar.xz
(自动识别格式)
极高压缩率。体积通常比 .tar.gz 小得多,但压缩时极为耗时和吃内存。常见于 Linux 内核源码包或软件发行版发布
.zip Zip (标准跨平台) zip -r archive.zip /path unzip archive.zip 跨平台兼容性最佳。在 Windows/Mac/Linux 间传递文件时的首选;缺点是无法天然保留 Linux 文件的特殊权限与所有者属性
.7z 7-Zip (LZMA/LZMA2) 7z a archive.7z /path 7z x archive.7z 高压缩率,支持强大的 AES-256 加密与分卷压缩,常用于大文件归档和跨平台加密传输
.gz gzip (仅单文件) gzip file gunzip file.gz 仅能压缩单个文件(压缩后直接覆盖原文件,不具备打包功能)。Linux 下常用于对日志文件(如 .log)直接进行压缩

软件包管理

rpm 包管理器

常用操作类别 选项 选项含义与作用说明 典型示例命令 注意事项 / 提示
查询 (Query) -qa query all:查询系统已安装的所有 RPM 包 rpm -qa | grep nginx 运维中最高频的查询组合,配合 grep 过滤指定软件
-qc query configfiles:列出已安装软件包的配置文件路径 rpm -qc nginx 快速定位 /etc 等目录下的核心配置文件,排查修改项
-qd query docfiles:列出已安装软件包的文档与帮助文件路径 rpm -qd nginx 查看 README、man 手册、许可协议等相关文档
-qf query file:查看某个具体文件/命令归属于哪个 RPM 包 rpm -qf /usr/sbin/nginx 知道命令或文件路径,反查其来源包(必填文件的绝对路径)
-qi query info:查看已安装软件包的详细信息(版本/描述等) rpm -qi nginx 显示版本、发布者、打包时间、功能描述等元数据
-ql query list:列出已安装软件包释放的所有文件路径 rpm -ql nginx 快速定位软件释放的所有可执行文件、日志和配置文件目录
-qpl query package list:预览未安装的 .rpm 文件包含的文件 rpm -qpl package.rpm 在正式安装前,先检查该本地 .rpm 包会把文件放进哪些目录
安装 / 更新 -i install:安装新的 RPM 软件包 rpm -ivh package.rpm 无法自动解决依赖:若缺少依赖会报错终止,需手动先装依赖包
-U Upgrade:升级软件包(若未安装则安装 rpm -Uvh package.rpm 实际运维中最常用的安装命令,比单纯的 -i 更具通用性
-v verbose:显示指令执行过程的详细信息 rpm -ivh package.rpm 通常与 -i-U 组合使用,观察安装过程
-h hash:显示安装进度条(输出 # 号) rpm -ivh package.rpm 配合 -v 一起使用,提供直观的百分比进度反馈
--nodeps no dependencies:强制忽略依赖关系 rpm -ivh --nodeps package.rpm 慎用!强制安装可能导致软件因缺少关键依赖而无法运行
--force force强制覆盖安装 rpm -ivh --force package.rpm 相当于 --replacepkgs + --replacefiles + --oldpakge,用于修复损坏的软件包
卸载 (Erase) -e erase:卸载/移除已安装的 RPM 软件包 rpm -e nginx 参数填写的是包名(如 nginx),而不是 .rpm 文件文件名
-e --nodeps 卸载时忽略其他软件对该包的依赖 rpm -e --nodeps nginx 强行卸载底层依赖包可能会破坏其他依赖它的上层应用

注意:

  • 软件中被手动修改过的文件不会随重装被覆盖,也不会随卸载而删除;如果加上 --force 则会覆盖
  • -hv (显示详细信息及进度条)可以用于安装 -ivh 也可用于卸载 -evh

yum / dnf 包管理器

YUM 和 DNF 是 Red Hat 系 Linux(如 RHEL、CentOS、Rocky Linux 等)中用于自动解决依赖、从网络源一键下载并安装软件的高级包管理工具。
在现代 Linux 系统中,输入 yum 会自动重定向调用 dnf,两者的常用命令语法完全通用。

软件包仓库配置

场景类型 配置文件内容结构(/etc/yum.repos.d/xxx.repo 参数拆解与注意事项
在线软件源
(以阿里云 EPEL 源为例)
[epel-aliyun]
name=Extra Packages for Enterprise Linux
baseurl=https://mirrors.aliyun.com/epel/7/$basearch
enabled=1
gpgcheck=1
gpgkey=https://mirrors.aliyun.com/epel/RPM-GPG-KEY-EPEL-7
baseurl:使用 http://https:// 协议,指向远程 Web 镜像服务器。
$basearch:Yum 内置变量,自动匹配 CPU 架构(如 x86_64)。
前提条件:服务器需能正常访问外网或内网镜像站。
本地光盘/ISO 源
(以挂载 ISO 为例)
[local-cdrom]
name=Local ISO Media
baseurl=file:///media/cdrom
enabled=1
gpgcheck=1
gpgkey=file:///media/cdrom/RPM-GPG-KEY-redhat-release
baseurl:使用 file:// 协议(注意协议头加路径共三个斜杠 file:///)。
前提条件:需先挂载光盘,如 mount /dev/sr0 /media/cdrom
• 若无网且无需校验,可设 gpgcheck=0

安装、更新与卸载

分类 命令示例 功能说明 运维实用技巧 / 提示
安装与重装 yum install -y <包名> 安装指定软件包并自动解决依赖,
-y 跳过交互确认
自动化脚本必备参数 -y;支持同时安装多个包
yum reinstall <包名> 重新安装指定软件 修复误删文件或二进制损坏时的快捷手段,依赖不会被重新安装
yum localinstall <本地.rpm> 安装本地 RPM 包,并自动联网下载解决依赖 相比 rpm -i,能自动补全缺失的依赖包
更新与升级 yum check-update 检查当前系统中所有可升级的软件包 仅列出可更新清单,不发起实际更新操作
yum update -y [包名] 升级指定包或系统所有已安装的软件包,-y 跳过交互确认 生产环境慎用全局升级,建议接具体包名单独更新
yum update --excludepkg=<包名> 升级软件包,但排除指定软件包 避免自动升级内核(kernel)或生产数据库
卸载与清理 yum remove <包名> 卸载指定软件包及其关联依赖 卸载前需核对依赖链,防止误删系统核心库
yum autoremove 自动清除系统中不再被任何软件使用的无用依赖 清理长期积累的“孤立依赖包”,释放磁盘空间
yum clean all 清理本地缓存的元数据与软件包 排错必备:源报错、下载卡死或更新异常时首选
yum makecache 重新建立本地软件包元数据缓存 clean all 后执行,可大幅提升后续搜索与安装速度
查询与搜索 yum search <关键字> 在软件源中根据名称和描述进行模糊搜索 不确定精确包名时使用
yum info <包名> 查看指定软件包的详细元信息(版本、大小、来源等) 类似 rpm -qi,但适用于未安装的源内软件包
yum list installed 列出系统中已安装的所有软件包 配合 grep 筛选,如 yum list installed | grep nginx
yum provides <路径/命令> 根据文件路径或命令反查其归属的软件包 高频神器:如 yum provides */ifconfig 查工具包
软件源管理 yum repolist 显示当前系统中已启用的软件源(Repository)列表 用于确认第三方源(如 EPEL、Docker 源)是否生效
yum-config-manager --enable <源ID> 动态启用或禁用指定的软件源 需安装 yum-utils 工具包
软件组操作 yum grouplist 列出可用的软件包组(如“开发工具”、“桌面环境”) 快速了解可进行批量安装的套件
yum groupinstall "Development Tools" 批量安装整个功能套件 部署编译环境(含 gccmake 等)的最佳方式
历史与撤销 yum history 查看 Yum 的历史操作事务列表及 ID 审计历史安装/升级记录
yum history undo <事务ID> 撤销指定的历史操作(版本回滚/卸载) 误装或升级导致故障时的“后悔药”
  • /var/log/dnf.log 记录了 yum 命令的相关操作
  • /var/log/dnf.rpm.log 记录了包的安装情况

搭建局域网私有软件仓库

环节 模块 / 节点 路径 / 配置内容 作用与处理逻辑
1. 官方源输入 官方 ISO 镜像 挂载至 /var/www/html/repo/BaseOS/
挂载至 /var/www/html/repo/AppStream/
光盘已自带 repodata/ 索引文件夹,直接通过 Nginx 暴露
2. 私有源输入 零散 RPM 包 存放于 /var/www/html/repo/custom/ 放置第三方或自主开发的裸 .rpm 文件,自己放的包需要使用 createrepo_c 生成索引
3. 索引构建 createrepo_c 执行:createrepo_c /var/www/html/repo/custom/ 扫描该目录下的所有 .rpm 包,并在该目录下生成 repodata/ 索引(含 repomd.xml
4. 自动维护 定时任务 (Cron) crontab -e
0 2 * * * root createrepo_c --update /var/www/html/repo/custom/
每天自动增量扫描新上传的 RPM 包并更新索引
5. Web 共享 Nginx 服务
(192.168.1.100)
/etc/nginx/conf.d/yum_repo.conf
nginx
server {
listen 80;
root /var/www/html/repo;
location / { autoindex on; }
}
监听 80 端口,开启目录遍历,将 BaseOS、AppStream 及 custom 目录通过 HTTP 协议暴露给局域网
6. 客户端调取 局域网 Client
(192.168.1.x)
/etc/yum.repos.d/lan-repo.repo
[lan-baseos]
name=LAN BaseOS
baseurl=http://192.168.1.100/repo/BaseOS
enabled=1
gpgcheck=0
[lan-custom]
name=LAN Custom
baseurl=http://192.168.1.100/repo/custom
enabled=1
gpgcheck=0
客户端通过 URL 拉取索引,实现自动解决依赖并安装官方与私有软件包

源码包安装

步骤 命令行 核心作用
Step 1: 准备环境 yum install -y gcc pcre-devel zlib-devel openssl-devel make 安装 C 语言编译器及 Nginx 依赖的底层开发库
Step 2: 配置预编译参数 ./configure --prefix=/usr/local/nginx --with-http_ssl_module 检查编译环境、指定安装目录,并启用需要的扩展功能模块
Step 3: 编译源码 make 将 C 语言源代码编译转化为机器可执行的二进制文件
Step 4: 写入系统安装 make install 将编译好的二进制文件和配置文件复制到指定的目标路径下

服务管理和系统启动流程

systemctl 管理服务

常用操作

分类 常用命令 作用与功能说明
基础服务控制 systemctl start <服务名> 启动指定服务
systemctl stop <服务名> 停止指定服务
systemctl restart <服务名> 重启指定服务
systemctl reload <服务名> 平滑加载配置(不中断服务)
systemctl status <服务名> 查看服务的当前运行状态与最新日志
开机自启管理 systemctl enable <服务名> 设置服务开机自动启动
systemctl disable <服务名> 禁止服务开机自动启动
systemctl enable --now <服务名> 立即启动服务并设置开机自启
systemctl is-enabled <服务名> 检查服务是否已设置开机自启
服务状态查询 systemctl is-active <服务名> 检查服务当前是否正在运行
systemctl list-units --type=service 列出目前已加载的所有服务单元
systemctl list-units --type=service --state=running 查看当前正在运行的服务列表
systemctl list-unit-files --type=service 查看系统中所有已安装服务的开机自启状态
systemctl list-failed 列出启动失败或处于报错状态的服务
安全与保护 systemctl mask <服务名> 屏蔽服务(锁定,使其无法手动或被其他服务调用启动)
systemctl unmask <服务名> 解除对服务的屏蔽
配置重载 systemctl daemon-reload 重新加载修改后的 Service 配置文件(修改 .service 文件后必敲)
系统电源管理 systemctl reboot 重启操作系统
systemctl poweroff 关闭操作系统(关机)
systemctl suspend 使系统进入休眠/挂起状态

服务单元配置文件

服务单元配置文件(Service Unit Configuration File)是 Systemd 用来定义、管理和控制 Linux 后台服务(守护进程/Daemon)的纯文本描述文件,后缀为 .service
安装的软件通常默认在 /usr/lib/systemd/system/ 创建了一个服务单元配置文件,文件名就是服务名。

设置开机启动命令 systemctl enable <服务名>,本质就是在 /etc/systemd/system/multi-user.target.wants/ 中创建了一个软链接,指向 /usr/lib/systemd/system/ 中的配置文件。

graph TD
    subgraph Storage ["1. 配置存储源"]
        UsrFile["/usr/lib/systemd/system/nginx.service<br/>(软件安装时自带的默认配置文件)"]
    end

    subgraph EnableDir ["2. 开机扫描挂载目录"]
        WantsDir["/etc/systemd/system/multi-user.target.wants/"]
    end

    subgraph Engine ["3. Systemd 引擎 (PID 1)"]
        Boot["系统开机启动"]
    end

    %% 流程关系
    Cmd["执行 systemctl enable nginx"] -->|"1. 创建软链接"| Link["软链接: nginx.service"]
    Link -->|"存放在"| WantsDir
    Link -.->|"指向"| UsrFile

    Boot -->|"2. 扫描挂载目录"| WantsDir
    WantsDir -->|"3. 顺着软链接读取"| UsrFile
    UsrFile -->|"4. 解析 ExecStart"| Launch["拉起后台服务进程"]

    %% 样式定义
    style Storage fill:#f9f9f9,stroke:#333
    style EnableDir fill:#e1f5fe,stroke:#0288d1
    style Engine fill:#e8f5e9,stroke:#388e3c

服务单元配置文件示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
[Unit]
# 服务的简短描述信息
Description=My Custom Python Web Service
# 帮助文档链接(可选,执行 systemctl status 时会展示)
Documentation=https://docs.example.com/my-app

# 启动顺序控制:指定本服务必须在网络服务(network.target)启动完成后再启动
After=network.target
# 依赖关系:如果网络未启动,尝试拉起网络服务(非强依赖,启动失败也不影响本服务继续尝试)
Wants=network.target

[Service]
# 服务启动类型:
# simple(默认):ExecStart 启动的进程就是主进程
# forking:程序自身会转入后台(如 Nginx),需配合 PIDFile 使用
# oneshot:执行一次性任务,完成后即退出
Type=simple

# 运行该服务进程的 Linux 用户和组(安全隔离,避免使用 root 运行)
User=www-data
Group=www-data

# 启动命令执行前的工作目录
WorkingDirectory=/var/www/my-app

# 环境变量设置(支持配置多个)
Environment="PORT=8080"
Environment="NODE_ENV=production"
# 也可以直接从外部文件加载环境变量
# EnvironmentFile=/var/www/my-app/.env

# 启动服务的绝对路径命令(注意:必须写绝对路径!)
ExecStart=/usr/bin/python3 /var/www/my-app/main.py

# 服务重新加载配置时的命令(可选,执行 systemctl reload 时触发)
ExecReload=/bin/kill -HUP $MAINPID

# 进程崩溃与自愈策略:
# on-failure:当进程返回非0退出码、被信号杀死或超时死机时自动重启
# always:无论以何种原因退出,一律自动重启
Restart=on-failure

# 进程异常退出后,等待 5 秒再尝试重新拉起
RestartSec=5s

# 防止死循环重启:如果 60 秒内连续重启超过 5 次,Systemd 将停止尝试并报错
StartLimitIntervalSec=60s
StartLimitBurst=5

# 资源限制(可选):限制该服务最大使用的内存为 512M
MemoryMax=512M
# 限制最高占用 1 个 CPU 核心(100% 代表单个 CPU 核心满载)
CPUQuota=100%

[Install]
# 挂载目标:指定当系统进入多用户模式(正常开机命令行环境)时启用该服务
# 执行 systemctl enable my-app.service 时,Systemd 会在 /etc/systemd/system/multi-user.target.wants/ 目录下建立该文件的软链接
WantedBy=multi-user.target

管理启动目标

在 Systemd 的架构中,启动目标(Target) 替代了传统 Linux 中运行级别(Runlevel)的概念。Target 本质上是一组服务单元(.service)及其他单元的逻辑分组与同步点。

分类 命令 详细说明 关联底层路径 / 原理
查询目标状态 systemctl get-default 查看系统开机时默认进入的 Target 读取 /etc/systemd/system/default.target 软链接
systemctl list-units --type=target 查看当前正在运行/已激活的 Target -
systemctl list-unit-files --type=target 列出系统中所有可用的 Target 配置文件 扫描 /usr/lib/systemd/system/*.target
修改默认目标 systemctl set-default multi-user.target 设置开机默认进入多用户命令行模式 创建软链接 default.target -> multi-user.target
systemctl set-default graphical.target 设置开机默认进入图形界面模式 创建软链接 default.target -> graphical.target
切换运行模式 systemctl isolate graphical.target 临时切换到图形界面(无需重启系统) 停止当前 Target 独有服务,拉起新 Target 关联服务
systemctl isolate multi-user.target 临时切换回命令行模式 关闭桌面 GUI 进程及关联图形服务
systemctl isolate rescue.target 切换到单用户救援模式 停止所有普通服务与用户会话,仅留根 Shell
快捷电源控制 systemctl reboot 重启系统 切换并执行 reboot.target
systemctl poweroff 关机 切换并执行 poweroff.target
systemctl suspend 系统挂起 / 休眠 切换并执行 suspend.target

Linux 系统的启动流程

graph TD
    %% 全局样式与方向控制
    direction TB

    %% --- BIOS 流程分支 ---
    subgraph BIOS_Branch ["BIOS (Legacy) + MBR 模式"]
        direction TB
        B1["<b>1. 硬件自检与 MBR</b><br/>• 上电 / 复位<br/>• BIOS 读取 NVRAM 配置<br/>• 硬件自检 (POST)<br/>• 读取硬盘 0 扇区 (512B)<br/>• 加载 MBR"]
        B2["<b>2. GRUB 分阶段引导</b><br/>• 执行 MBR Boot Loader (Stage 1)<br/>• 加载 MBR 保留扇区 (Stage 1.5 驱动)<br/>• 读取 /boot/grub2/grub.cfg (Stage 2 菜单)"]
        B3["<b>3. 内核引导与 initramfs</b><br/>• 加载内核 (vmlinuz) 入内存<br/>• 加载虚拟文件系统 (initramfs) 入内存<br/>• 内核挂载 initramfs 并执行 /init"]
        
        B1 --> B2 --> B3
    end

    %% --- UEFI 流程分支 ---
    subgraph UEFI_Branch ["UEFI + GPT 模式"]
        direction TB
        U1["<b>1. UEFI 固件初始化</b><br/>• 上电 / 复位<br/>• UEFI 初始化硬件 (SEC/PEI/DXE)<br/>• 读取 NVRAM 中的 Boot Manager 启动项"]
        U2["<b>2. ESP 分区与 Bootloader</b><br/>• 直接解析 FAT32 格式的 ESP 分区<br/>(/boot/efi/EFI/.../grubx64.efi)<br/>• 执行 UEFI 版 GRUB2<br/>• 读取 /boot/grub2/grub.cfg 显示菜单"]
        U3["<b>3. 内核引导与 initramfs</b><br/>• 加载内核 (vmlinuz) 入内存<br/>• 加载虚拟文件系统 (initramfs) 入内存<br/>• 内核挂载 initramfs 并执行 /init"]

        U1 --> U2 --> U3
    end

    %% --- 收敛节点:用户空间初始化 ---
    subgraph Shared_Stage ["4. 用户空间初始化 (两模式在此收敛)"]
        direction TB
        Init["<b>切换至真实系统并启动 PID 1</b><br/>• 切换至真实根文件系统 (switch_root)<br/>• 执行 /sbin/init (指向 Systemd, PID 1)<br/>• Systemd 解析 default.target (如 multi-user / graphical)<br/>• 并发拉起系统服务及依赖链<br/>• 启动 Getty / Display Manager 登录界面"]
    end

    %% 两条分支收敛到同一节点
    B3 --> Init
    U3 --> Init

    %% 节点与子图样式配置
    style BIOS_Branch fill:#fff3e0,stroke:#f57c00,stroke-width:2px
    style UEFI_Branch fill:#e3f2fd,stroke:#1976d2,stroke-width:2px
    style Shared_Stage fill:#f3e5f5,stroke:#7b1fa2,stroke-width:2px

    style B1 fill:#ffffff,stroke:#f57c00
    style B2 fill:#ffffff,stroke:#f57c00
    style B3 fill:#ffffff,stroke:#f57c00

    style U1 fill:#ffffff,stroke:#1976d2
    style U2 fill:#ffffff,stroke:#1976d2
    style U3 fill:#ffffff,stroke:#1976d2

    style Init fill:#ffffff,stroke:#7b1fa2

Linux 开机故障处理

故障场景 故障现象与含常见诱因 排查与修复方法
1. GRUB2 引导程序破坏 (Stage 1/MBR 损坏) 报错现象:开机直接黑屏并提示 Operating System not found;卡在 grub error: no such partition / grub rescue> 提示符下;或直接跳过硬盘引导转入第二启动项(如网络/光盘)。

常见诱因
• MBR 主引导记录或 ESP 分区 Boot Loader 被误擦除/破坏;
• 在已有的 Linux 系统后重装了 Windows,导致 Windows Boot Manager 强制覆盖了 MBR/引导扇区;
• 磁盘分区表损坏,导致 GRUB 无法定位物理启动扇区。
1. 使用 Linux 安装光盘/ISO 引导,进入救援模式(Rescue Mode)。
2. 切换环境:chroot /mnt/sysroot
3. 重新向磁盘写入 GRUB2 引导代码:
BIOS 模式grub2-install /dev/sda
UEFI 模式grub2-install --target=x86_64-efi --efi-directory=/boot/efi --bootloader-id=redhat
4. 退出并重启:exitreboot
2. GRUB2 配置文件丢失 (grub.cfg) 报错现象:开机直接停留在黑屏文本界面的 grub> 提示符,无法自动弹出内核选择菜单并卡住。

常见诱因
• 误删除了 /boot/grub2/grub.cfg(或 UEFI 下的配置文件);
• 手动修改 grub.cfg 时输入了错误配置或存在语法逻辑错误;
• 执行内核更新或软件包升级时中断,导致菜单生成失败。
方案 A(救援模式重构):
1. 光盘引导进入 Rescue Mode 并切换:chroot /mnt/sysroot
2. 重新生成配置文件:
BIOS 模式grub2-mkconfig -o /boot/grub2/grub.cfg
UEFI 模式grub2-mkconfig -o /boot/efi/EFI/redhat/grub.cfg

方案 B(GRUB 命令行手动临时引导):
grub> 界面手动指定路径启动:
1. grub> set root=(hd0,msdos1) 指定开机引导文件所在的根设备分区
2. grub> linux /vmlinuz-xxx root=/dev/mapper/rhel-root ro 加载内核并传递根目录参数(xxxTab 补全)
3. grub> initrd /initramfs-xxx.img 加载虚拟内存文件系统镜像(xxxTab 补全)
4. grub> boot
3. 整个 /boot 分区文件丢失 / 误删 报错现象:开机后提示 Missing operating system 或引导直接崩溃;进入救援界面检查发现 /boot 目录下空无一物(内核 vmlinuzinitramfsgrub2 全灭)。

常见诱因
• 运维误操作执行了 rm -rf /boot/*
• 独立 /boot 分区被错误挂载并被初始化/格式化;
• 底层存储块阵列损坏或文件系统崩溃导致 /boot 目录丢失。
1. 启动进入光盘 Rescue Mode 挂载网络或本地光盘源。
2. 挂载系统与挂载点:chroot /mnt/sysroot
3. 挂载光盘镜像到 /mnt 并重新安装内核软件包(生成 vmlinuzinitramfs):
rpm -ivh /mnt/BaseOS/Packages/kernel-core-x.x.x.rpm --force
4. 重装 GRUB2 引导程序与菜单:
grub2-install /dev/sda
grub2-mkconfig -o /boot/grub2/grub.cfg
5. 退出并重启。
4. 文件系统挂载故障 (/etc/fstab 错误) 报错现象:开机卡在 Emergency Mode(紧急模式)或 Maintenance Mode,提示 Cannot open access to console... 或文件系统检查失败(fsck error)。

常见诱因
/etc/fstab 中填写的 UUID、设备名或文件系统类型错误;
• 挂载了已移除的硬件磁盘或已断开的 NFS/iSCSI 网络存储,且未设置 nofail
• 服务器异常断电导致分区逻辑损坏,触发了系统自动检查(fsck/xfs_repair)失败。
1. 根据提示输入 root 密码进入紧急命令行。
2. 重新以读写模式挂载根分区:mount -o remount,rw /
3. 检查并修改 /etc/fstab:注释掉增删的非必要挂载项,或修正拼写错误(若是因为不关键的分区导致,可在该行 defaults 后加上 ,nofail 参数防止卡开机)。
4. 若是磁盘损坏,针对报错分区执行修复:xfs_repair /dev/sdb1fsck -y /dev/sdb1
5. 执行 systemctl reboot 重启。
5. 忘记并重置 root 密码 报错现象:无法通过 root 账号与密码登录系统,拒绝访问,导致无法进行系统运维与配置更改。

常见诱因
• 系统管理员遗忘或输错了 root 密码;
• 离职交接遗漏,或服务器遭到未经授权的密码篡改;
• 自动化部署脚本误修改了凭据配置。
方法:通过 GRUB 菜单修改引导参数
1. 重启系统,在 GRUB 菜单界面按 e 键进入编辑模式。
2. 找到以 linux 开头的行,删掉 ro 之后的所有内容并在末尾添加:rd.break
3.Ctrl + x 启动进入单用户内核终端。
4. 依次执行以下命令重置密码:
mount -o remount,rw /sysroot
chroot /sysroot 从内存环境进入硬盘上的真实操作系统环境
passwd root 输入新密码
touch /.autorelabel (重要:触发表重新打标,防止 SELinux 阻止登录)
exitexit
6. 加密与解密 GRUB2 引导程序 报错/加密现象:在 GRUB 菜单按 e 编辑内核参数或进入 c 命令行时,系统强制弹窗要求输入受保护的用户名与密码。

配置与触发诱因
配置加密:出于等保合规与安全加固需求,防止有物理/虚拟机接触权限的人通过追加 rd.break 直接绕过密码获取 root 权限;
解密/故障救援:运维人员忘记了设置的 GRUB 菜单密码,导致无法进入单用户模式维护系统。
配置加密 (设置密码):
1. 执行 RHEL 9 官方加密命令:grub2-set-password
2. 根据提示连续输入两次设置的 GRUB 密码,配置即时生效(自动生成 user.cfg)。

解密 / 取消加密 (忘记 GRUB 密码时):
1. 使用 ISO 光盘引导进入 Rescue Mode;
2. 切换环境:chroot /mnt/sysroot
3. 直接删除密码凭据文件即可解密:
rm -f /boot/grub2/user.cfg /boot/efi/EFI/redhat/user.cfg

系统日志服务和时间管理服务

系统日志服务

对比维度 systemd-journald rsyslog
存储格式 二进制文件(含 Hash 索引与字段元数据) 纯文本文件(如 /var/log/messages
存储路径 /run/log/journal/(内存) /var/log/ 目录下各类文本日志文件
查询方式 专用命令行工具 journalctl 标准 Linux 文本处理工具(catgrepawktail 等)
检索效率 极高(基于索引字段检索,如 _SYSTEMD_UNIT_PID 一般(依赖正则表达式逐行扫描大文本)
启动时机 内核加载后极早期启动(initramfs 阶段即可捕获) 系统引导较后期作为常规服务启动

systemd-journald 日志服务

分类 常用命令示例 功能与作用说明
基础查看 journalctl 查看系统所有日志(默认按时间从旧到新排列,自动调用 less 分页)。
journalctl -n 20 仅显示最新的 20 条日志(相当于 tail -n 20)。
journalctl -f 实时追踪最新日志输出(相当于 tail -f)。
按服务/进程过滤 journalctl -u sshd.service 仅查看指定服务单元(Unit)的所有日志。
journalctl -u nginx -f 动态实时查看 Nginx 服务的日志。
journalctl _PID=1 过滤指定 PID 进程产生的日志。
journalctl _COMM=sshd 过滤指定进程名称的日志。
按时间段过滤 journalctl --since "2026-08-30 00:00:00" 查看指定时间之后产生的日志。
journalctl --since "10 min ago" 查看最近 10 分钟内的日志。
journalctl --since "1 hour ago" --until "15 min ago" 查看指定时间区间内的日志。
按系统启动序列过滤 journalctl -b 仅查看本次开机后的所有日志。
journalctl -b -1 查看上一次开机(上个 Boot 周期)的完整日志。
journalctl --list-boots 列出磁盘中保存的所有开机历史记录及其索引编号。
按日志级别过滤 journalctl -p err 仅显示错误(err)及以上级别的日志(级别:emerg, alert, crit, err, warning, notice, info, debug)。
journalctl -p err..warning 过滤显示从 Error 到 Warning 级别的日志。
高级与运维诊断 journalctl -xe 排错神器-x 附带系统专家诊断说明,-e 直接跳转到末尾(常用于 systemctl start 失败后的快速诊断)。
journalctl -o json-pretty 以美化后的 JSON 格式输出日志的所有底层元数据字段。
journalctl --disk-usage 查看日志在磁盘上占用的真实空间大小。
journalctl --vacuum-size=500M 手动清理日志,将磁盘占用压缩限制在 500MB 以内。

配置持久化存储

1
2
3
4
5
6
vim /etc/systemd/journald.conf
[Journal]
#Storage=auto
# auto:当/var/log/journal目录存在,就是持久化存储,如果不存在就是易失性存储 /run/log/journal
# none:都不会持久化存储
# persistent:无论/var/log/jounal目录是否存在都是持久化存储,目录不存在会自动创建

rsyslog 日志服务

常用命令
常用命令/工具 针对的日志文件 典型使用命令示例 适用场景与功能
tail /var/log/messages tail -f /var/log/messages 动态监听通用系统日志(系统事件、服务启动、硬件变动等)。
/var/log/secure tail -n 50 /var/log/secure 安全审计:查看最近 50 条登录、用户鉴权、sudo 授权日志。
grep /var/log/messages grep -i "error" /var/log/messages 快速在文本日志中检索包含关键词(如 error / fail)的行。
/var/log/secure grep "Failed password" /var/log/secure 检索 SSH 爆破与密码错误登录记录。
less / more /var/log/maillog less /var/log/maillog 打开大体积文本日志文件(如邮件日志),支持上下翻页与 / 关键词搜索。
dmesg 内核环形缓冲区 dmesg -T | grep -i "eth" 查看系统开机阶段及硬件驱动(PCI/USB/网卡/磁盘等)的内核原生输出。
logrotate /etc/logrotate.d/* logrotate -f /etc/logrotate.conf 日志切割工具:配合 rsyslog 定期将文本日志按天/按大小切割归档(如生成 messages-20260830.gz)。
部署集中式日志服务器
graph TD
        Server[中央日志服务器 - IP: 192.168.1.100]

        ClientA[客户端 01 Host A - IP: 192.168.1.10]
        ClientB[客户端 02 Host B - IP: 192.168.1.20]
        ClientC[客户端 03 Host C - 故障节点: 主机挂了/程序无法启动]

    ClientA -->|发送日志 UDP/TCP 514| Server
    ClientB -->|发送日志 UDP/TCP 514| Server
    ClientC -.->|崩溃前最后日志传输| Server
  • 服务端配置
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 编辑服务器配置文件
vim /etc/rsyslog.conf

# 取消以下四行的注释(启用 UDP 514 和 TCP 514 接收)
module(load="imudp")
input(type="imudp" port="514")
module(load="imtcp")
input(type="imtcp" port="514")

# 追加自定义模板:将不同客户端的日志自动存入对应主机名目录
$template RemoteLogs,"/var/log/remote/%HOSTNAME%/%PROGRAMNAME%.log" # 定义模板
*.* ?RemoteLogs # 应用模板,这里不会解析变量所以要先把变量写到模板里

# 放行防火墙并重启服务
firewall-cmd --permanent --add-port=514/tcp --add-port=514/udp
firewall-cmd --reload
systemctl restart rsyslog
  • 客户端配置
1
2
3
4
5
6
7
8
vim /etc/rsyslog.conf
# 在文件末尾追加
*.* @@192.168.1.100:514
# *.* 表示不限来源(auth, kern, cron等),不限日志级别(info, notice, warning 等)
# @ 表示 UDP,@@ 表示 TCP

# 重启客户端 rsyslog 服务
systemctl restart rsyslog
logrotate 日志轮询服务

logrotate 是一个用于自动切割、压缩、轮转和清理日志文件的系统工具。
logrotate 的主配置文件是 /etc/logrotate.conf,通常我们在 /etc/logrotate.d/ 目录下为具体服务(如 Nginx、MySQL、自定义应用)创建独立的配置文件。

/etc/logrotate.d/nginx 内容示例

1
2
3
4
5
6
7
8
9
10
11
12
13
/var/log/nginx/*.log {
daily # 轮转周期:每天执行一次(可选 weekly, monthly)
rotate 7 # 保留最近 7 个备份文件,旧的自动删除
missingok # 如果日志文件不存在,忽略错误继续执行
notifempty # 如果日志文件为空,不进行轮转
compress # 轮转后的历史日志进行 gzip 压缩 (.gz)
delaycompress # 延迟压缩(把上一次的备份在下一次轮转时再压缩,防止正在写入的文件被压缩报错)
create 0640 nginx nginx # 切割后创建新的空日志文件,并指定权限与属主属组
sharedscripts # 针对通配符匹配到的所有日志,下面的 postrotate 脚本只执行一次
postrotate # 切割完成后执行的命令/脚本
/usr/bin/systemctl kill -s HUP nginx.service >/dev/null 2>&1 || true
endscript # 脚本结束标识
}

logger 命令手动写入日志

logger 是一个用于向系统日志系统手动写入日志消息的命令行工具。
运行 logger 命令时,它会向系统内核或日志套接字(syslog)发送一条消息。这条消息会同时被 systemd-journald 和 rsyslog 捕获并记录。

参数 长参数 作用说明
-t --tag <TAG> 为日志指定一个标记/标签(标识日志来源,如脚本名或模块名)。
-p --priority <facility.level> 指定日志的设施(Facility)优先级(Level),如 user.noticelocal0.err
-i --id 自动在日志中附带当前运行进程的 PID

时间管理

管理系统的时间和时区

运维 / 系统需求 date 命令实现 timedatectl 命令实现 功能与适用场景说明
查看系统当前时间与状态 date timedatectl date 仅显示一行本地时间;timedatectl 显示本地时间、UTC 时间、时区及 chronyd 对时状态。
格式化输出指定时间 date "+%Y-%m-%d %H:%M:%S" (不支持格式化输出) date 专用于脚本内拼接时间格式(如 2026-08-31 21:55:00);timedatectl 无此功能。
手动修改系统日期和时间 date -s "2026-08-31 21:55:00" timedatectl set-time "2026-08-31 21:55:00" 强制将系统时间设定为指定值(使用 timedatectl 前需先关闭 chronyd 自动对时)。
手动仅修改系统日期 date -s "2026-08-31" timedatectl set-time "2026-08-31" 只修改日期,保持当前时分秒不变。
查看 / 修改系统时区 date +%Z (仅查看时区名) timedatectl set-timezone Asia/Shanghai date 无法直接改时区;timedatectl 允许通过 list-timezones 查询并一键修改时区。
开关自动对时 (不支持控制服务) timedatectl set-ntp true
timedatectl set-ntp false
date 无对时控制能力;timedatectl 可一键开启或关闭后台 chronyd 时间同步功能。
推算过去或未来时间 date -d "3 days ago" "+%Y%m%d"
date -d "next week" "+%Y-%m-%d"
(不支持时间计算) 脚本必备date 支持计算相对日期;timedatectl 无此功能。
时间戳转换与生成 date "+%s" (生成时间戳)
date -d @1756677272 (转换时间戳)
(不支持时间戳操作) date 独有功能,用于获取 Unix 时间戳或将时间戳解析回标准日期。
硬件时钟 (RTC) 管理 (不支持直观设置 RTC) timedatectl set-local-rtc 0 timedatectl 可直接配置主板硬件时钟是否使用 UTC(推荐设置为 0 保持 UTC)。

chronyd 时间校准服务

操作 命令 作用
查看时间同步源 chronyc sources -v 最常用。列出所有配置的 NTP 服务器及其连接状态(^* 表示当前正在使用的源,^+ 表示备选源),-vverbose 的缩写,意思是“详细模式”。
手动添加 NTP 源 chronyc add server <IP/域名> iburst 在不修改配置文件的情况下,临时动态添加一个 NTP 上游服务器。
手动删除 NTP 源 chronyc delete <IP/域名> 动态移除某个已配置的 NTP 时间源。

配置局域网时间同步

  • 服务端
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 1. 编辑 chrony 配置文件
vim /etc/chrony.conf

# 2. 允许局域网内的客户端网段连接本服务器获取时间
# 根据实际局域网网段修改(例如:192.168.1.0/24 或 10.0.0.0/8)
allow 192.168.1.0/24

# 3. 孤岛模式(离线权威时间源)
# 即使本服务器无法连接外网 NTP 源,也强制将本机系统时间作为权威时间源提供给客户端
# stratum 10 表示层级为 10(数值越小优先级越高,10 适合内网孤岛源)
local stratum 10

# 如果启用了 firewalld 防火墙,必须放行 UDP 123 端口
firewall-cmd --permanent --add-service=ntp
firewall-cmd --reload
  • 客户端
1
2
3
4
5
6
# 1. 编辑 chrony 配置文件
vim /etc/chrony.conf

# 2. 将上游时间源指向局域网 NTP 服务器的 IP 地址
# iburst 参数可以让客户端在刚启动时快速发送 4 个包完成初始化对时
server 192.168.1.100 iburst

内核和内核参数

内核概述

Linux 内核(Kernel)是操作系统的核心掌控者与底层大管家。
它运行在最高权限区(Ring 0),向下直接操纵物理硬件,向上为应用程序提供安全稳定的运行环境。主要负责 5 件核心大事:

  • 进程调度:决定谁能使用 CPU 及用多久,实现多任务并发。
  • 内存管理:分配与隔离物理内存,通过“虚拟内存”防止程序越界互相干扰。
  • 文件系统 (VFS):把各种磁盘和存储设备抽象成统一的文件接口(“一切皆文件”)。
  • 网络协议栈:处理 TCP/IP 封包、路由与数据传输。
  • 设备驱动:作为“翻译官”,指挥网卡、显卡、磁盘等硬件工作。
graph TD
    subgraph 用户空间
        A[应用 / 工具 / 服务] --> B[glibc 库]
    end

    B --> C[系统调用 Syscall]

    subgraph 内核空间
        C --> KernelCore[内核核心子系统: 进程 / 内存 / VFS / 网络 / 驱动]
        I[内核模块] -.-> KernelCore
    end

    KernelCore --> J[物理硬件]

内核模块

内核模块(Kernel Module,扩展名 .ko)是 Linux 内核动态扩展功能的“插件”机制。
它允许在系统无需重新编译内核、无需重启机器的情况下,将代码动态加载到运行中的内核空间,或从中卸载。

常见分类

  • 设备驱动程序:最常见的模块(如 Nvidia 显卡驱动、Realtek 网卡驱动、NVMe 磁盘驱动)。
  • 文件系统驱动:对某种特定存储格式的支持(如 NTFS、exFAT、OverlayFS 等)。
  • 网络与安全插件:网络协议扩展或高级防火墙功能(如 WireGuard VPN、ip_tables 扩展模块、eBPF 相关模块)。
运维 / 管理需求 推荐命令 命令功能与作用解析
查看已加载模块 lsmod 列表显示当前运行在内核空间的所有模块及其依赖关系。
查看模块详细信息 modinfo <模块名> 查看模块的版本、作者、依赖项以及支持的参数(无需先加载)。
智能加载模块 modprobe <模块名> 最推荐。通过模块名在标准库中自动检索路径,并优先加载该模块依赖的所有上游模块。
卸载模块 modprobe -r <模块名>
rmmod <模块名>
modprobe -r 会自动清理无用的空闲依赖模块;rmmod 仅强行卸载指定的单一模块。
指定路径强制加载 insmod /path/to/mod.ko 专门用于通过绝对路径直接注入非标准目录下的 .ko 文件(不自动处理模块依赖)。
开机自动加载模块 vim /etc/modules-load.d/custom.conf 在文件中直接写入需要开机加载的模块名称(一行一个)。

/proc 目录

/proc 是 Linux 系统中一个非常特殊的目录,它并不是存在于硬盘上的物理文件夹,而是一个基于内存的虚拟文件系统(procfs,Process Filesystem)。
当系统运行时,Linux 内核把系统硬件状态、内核运行参数、进程详细信息等动态数据,以“文件”的形式映射到 /proc 目录中,供管理员和应用程序读取或修改。

路径 / 文件名 对应包含的系统信息
/proc/cpuinfo CPU 详细规格信息(型号、主频、缓存、flags 指令集支持等)
/proc/meminfo 系统内存与 Swap 交换分区的详细使用状况(总量、可用、缓存等)
/proc/partitions 块设备及其分区列表(主/次设备号、块数量、设备名称)
/proc/filesystems 当前内核已支持/已加载的文件系统类型列表(如 ext4, xfs, overlay 等)
/proc/cgroups 内核 **Control Groups(控制组)**的配置与子系统启用状态
/proc/modules 当前已被内核加载的所有模块列表
/proc/mounts 当前系统已挂载的所有文件系统列表
/proc/sys/ 内核参数控制目录(网络、虚拟内存、安全等),向内部文件写入值可实现实时内核调优
/proc/<PID>/ 某个指定进程(PID)的全部运行上下文
/proc/<PID>/cgroup 显示该指定进程当前被分配到了哪些 cgroup 资源控制组中(Docker/K8s 容器中常用来判断进程所在的 Pod 或容器 ID)。
/proc/<PID>/cmdline 启动该进程所使用的完整命令行参数
/proc/<PID>/cwd 符号链接,指向该进程当前的工作目录
/proc/<PID>/exe 符号链接,指向该进程对应的执行文件绝对路径
/proc/<PID>/environ 该进程运行时的所有环境变量
/proc/<PID>/fd/ 目录,包含该进程打开的所有文件描述符(网络套接字、磁盘文件等)。
/proc/<PID>/status 包含该进程的运行状态、内存占用、父进程 PID 及 UID/GID。

tuned-adm 内核调优

Tuned 是 Linux 系统(尤其在 RHEL / CentOS / Rocky Linux / Fedora 中默认集成)中用于自动化性能调优的系统服务。

运维 / 管理需求 常用 tuned-adm 命令 功能与作用解析
查看当前运行与推荐配置 tuned-adm active 显示系统当前正生效的 Tuned 调优 Profile 方案。
让系统推荐最适合的方案 tuned-adm recommend RHCSA 考点。让 Tuned 根据当前系统硬件(如虚拟机、物理服务器等)推荐最佳方案。
列出所有预设方案 tuned-adm list 显示系统支持的所有内置 Profile 方案及其简介。
一键切换/应用调优方案 tuned-adm profile <方案名> 立即将系统的性能策略切换至指定的 Profile(无需重启系统)。
关闭所有调优配置 tuned-adm off 恢复系统默认设置,暂停 Tuned 策略生效。

磁盘管理

分区方案

对比维度 MBR (Master Boot Record) GPT (GUID Partition Table)
提出时间与标准 1983 年(IBM PC DOS 时代标准) 1990 年代末(EFI / UEFI 规范的一部分)
最大支持磁盘容量 2 TiB (基于 32 位 LBA 及 512 字节扇区计算) 8 ZiB (94 亿 TB,基于 64 位 LBA 计算)
分区数量限制 最多 4 个主分区
(或 3 主分区 + 1 扩展分区内嵌套逻辑分区)
无理论上限
(Windows 默认限制为 128 个分区)
数据冗余与安全性 无备份
(分区表仅存于首扇区 LBA 0,损坏即丢失整盘分区)
首尾双备份 + CRC32 校验
(磁盘头部与末尾均保存分区表,支持自动修复)
分区识别方式 1 字节的分区类型代码(如 0x83 代表 Linux) 128 位 GUID(全局唯一标识符)
主引导记录位置 固定的首扇区(字节 0~445 存放 Boot Code) LBA 0 设为 Protective MBR
(防止旧工具误将 GPT 识别为空盘而覆盖)
推荐引导模式 Legacy BIOS (或 UEFI 的 CSM 兼容模式) UEFI (现代操作系统与硬件的标准组合)
Linux 常用分区工具 fdisk / parted gdisk / parted
  • MBR 分区
graph TD
    subgraph MBR ["MBR 结构 (≤ 2TB)"]
        direction TB
        subgraph S0 ["LBA 0 (512B)"]
            Code["Boot Code (446B)"]
            Table["DPT 分区表 (64B)"]
            Sig["Flag (0x55AA, 2B)"]
        end
        
        subgraph Parts ["数据区"]
            P1["主分区 1"]
            P2["主分区 2"]
            P3["主分区 3"]
            subgraph Ext ["扩展分区"]
                L1["逻辑分区 1"]
                L2["逻辑分区 2"]
            end
        end
    end

    Table --> P1
    Table --> P2
    Table --> P3
    Table --> Ext
  • GPT 分区
graph TD
    subgraph GPT ["GPT 结构 (支持 > 2TB)"]
        direction TB
        
        subgraph Head ["主 GPT (磁盘头部)"]
            LBA0["Protective MBR"]
            LBA1["主 GPT Header"]
            LBA2["分区表项"]
        end
        
        subgraph Data ["数据区"]
            P1["分区 1"]
            PN["分区 N..."]
        end
        
        subgraph Tail ["备份 GPT (磁盘尾部)"]
            BLBA1["备份分区表项"]
            BLBA0["备份 GPT Header"]
        end
    end

    LBA2 --> P1
    LBA2 --> PN
    LBA1 -. 镜像备份 .-> BLBA0
    LBA2 -. 镜像备份 .-> BLBA1

分区工具

对比维度 / 工具 fdisk gdisk parted
工具定位 传统 MBR 分区工具(现代版本也支持 GPT,但在 GPT 上功能不如 gdisk 丰富) 专为 GPT 设计的分区工具(界面、快捷键与 fdisk 高度保持一致) 通用大块存储与脚本化分区工具(完全支持 MBR 与 GPT)
交互式体验 支持(菜单驱动,基于单字符快捷指令,如 n, d, p, w 支持(菜单驱动,快捷键与 fdisk 保持一致,增加专家模式 x 双模式(支持交互式命令行提示符 (parted),也支持纯命令行参数)
变更生效机制 内存暂存,手动写入
(修改全在内存缓冲区,执行 w 写入并退出,执行 q 不保存放弃)
内存暂存,手动写入
(修改全在内存缓冲区,执行 w 写入并退出,执行 q 不保存放弃)
即时生效,无撤销
(命令一旦回车即直接对磁盘表生效,没有 w 保存过程,误操作风险高)
最佳适用场景 快速处理 2TB 以下的传统 MBR 磁盘分区;RHCSA/RHCE 基础存储运维 专门用于 2TB 以上 GPT 磁盘的精确分区、备份/恢复 GPT 头及 GUID 转换 自动化 Shell 脚本部署、大于 2TB 的 GPT 分区操作、调整分区大小(resize)
进入交互 fdisk /dev/sdb gdisk /dev/sdb parted /dev/sdb
查看分区表 fdisk -l /dev/sdb
(交互内: p)
gdisk -l /dev/sdb
(交互内: p)
parted /dev/sdb print
创建新分区 交互内按 n -> 选择类型/编号 -> 指定起始与结束扇区(如 +5G 交互内按 n -> 指定编号/起始/结束扇区 -> 输入 GUID code(如 8300 parted /dev/sdb mkpart primary ext4 1MiB 5GiB
设置分区表类型 交互内按 g(新建 GPT)或 o(新建 MBR) 默认进入即强制转换为 GPT 逻辑 parted /dev/sdb mklabel gpt
(或 mklabel msdos 设置为 MBR)
删除分区 交互内按 d -> 指定分区号 交互内按 d -> 指定分区号 parted /dev/sdb rm 1
保存并退出 交互内按 w 交互内按 w 无需保存(执行即写入,使用 quit 退出)
放弃并退出 交互内按 q 交互内按 q 无(操作已即时写入)

创建文件系统

功能 示例指令 解析
标准通用格式 mkfs -t <文件系统类型> <设备路径> mkfs -t xfs /dev/sdb1
(通过 -t 参数指定类型,工具内部自动调用 mkfs.xfs)
快捷专有格式 mkfs.<文件系统类型> <设备路径> mkfs.xfs /dev/sdb1
直接调用具体工具,语法简练
查询文件系统类型及UUID blkid 只有文件系统创建了之后,才有UUID

挂载和卸载文件系统

  • mount 临时挂载文件系统
参数 / 选项 作用解析与使用说明 典型示例 / 命令写法
-a 挂载 /etc/fstab 中的未挂载条目
自动读取并挂载 /etc/fstab 中所有配置了 auto 选项且当前尚未挂载的文件系统。常用于校验配置文件语法无误。
mount -a
-r 只读挂载(相当于 -o ro
禁止在该文件系统内进行任何写入、修改或删除操作。
mount -r /dev/sdb1 /data
-w 读写挂载(相当于 -o rw,默认值)
允许在该文件系统内正常读写与创建文件。
mount -w /dev/sdb1 /data
-t 显式指定文件系统类型
手动告知内核设备的文件系统格式(如 xfs, ext4, vfat, iso9660 等)。未指定时内核会自动尝试识别。
mount -t xfs /dev/sdb1 /data
-L 基于卷标(LABEL)挂载设备
使用文件系统的逻辑名称(卷标)进行挂载,避免受设备路径变化影响。

不同文件系统卷标管理命令:
XFS:设置 xfs_admin -L 'rhcsa' /dev/sdb1 ;清除 xfs_admin -L '--' /dev/sdb1
EXT:设置 e2label /dev/sdb1 'rhce' ;清除 e2label /dev/sdb1 ''
mount -L "rhcsa" /data
-U 基于 UUID 挂载设备
使用文件系统唯一标识符(UUID)挂载,生产环境与 /etc/fstab 最推荐的挂载方式
mount -U "a1b2c3d4-..." /data
-o 指定额外的挂载选项
传递一个或多个以逗号分隔的低层挂载策略控制选项(如 -o ro,noexec,nosuid)。
mount -o remount,rw /
defaults 默认挂载组合
包含 rw, suid, dev, exec, auto, nouser, async 的预设选项集合,日常运维最常用。
mount -o defaults /dev/sdb1 /data
remount 在线重新挂载
在无需卸载(umount)设备的前提下,实时修改已挂载文件系统的挂载选项(如只读转读写)。
mount -o remount,rw /
ro / rw 只读 / 读写控制
ro 为强制只读;rw 为允许读写。
mount -o ro /dev/sdb1 /backup
async / sync 异步 / 同步写入模式
async(默认):修改先写内存缓冲区,再由内核定时刷盘,性能更高;
sync:所有写操作同步直接写入物理磁盘,安全性更高但性能较低。
mount -o sync /dev/sdb1 /data
atime / noatime 访问时间戳记录
atime(默认):每次读取文件或目录时更新访问时间;
noatime:禁用更新访问时间,大幅降低磁盘写入,显著提升 I/O 性能。
mount -o noatime /dev/sdb1 /data
auto / noauto 自动挂载支持
auto(默认):运行 mount -a 或开机时自动挂载;
noauto:跳过自动挂载,仅在显式手动执行 mount 命令时挂载。
mount -o noauto /dev/sdb1 /media
exec / noexec 可执行文件运行权限
exec(默认):允许运行该分区内的二进制文件及脚本;
noexec:禁止直接运行该分区内的可执行文件,用于 /tmp 等目录安全加固。
mount -o noexec /tmp
dev / nodev 设备文件解析支持
dev(默认):识别并支持分区内的块/字符设备文件(/dev 节点);
nodev:忽略并禁止解析挂载点内的设备节点。
mount -o nodev /home
suid / nosuid SUID / SGID 提权支持
suid(默认):允许 set-user-identifier 位生效;
nosuid:屏蔽 SUID/SGID 位,防止普通用户利用该分区上的可执行文件越权提权。
mount -o nosuid /var
user / nouser 普通用户挂载权限
user:允许非 root 普通用户挂载(须配合 /etc/fstab 配置);
nouser(默认):仅允许 root 用户执行挂载。
mount -o user /dev/cdrom /mnt
  • unmount 临时卸载文件系统
参数 / 选项 作用解析与使用说明 典型示例 / 命令写法
标准卸载 指定设备路径或挂载点目录进行卸载(最常用) sudo umount /dev/sdb1
sudo umount /data
-v 显示详细过程 (Verbose)
输出卸载的具体进度与结果信息。
sudo umount -v /data
-l 懒惰卸载 (Lazy Unmount)
立即将设备从文件系统层级拆离,待该设备上的所有活动进程结束后再清理相关引用。
专门解决 target is busy 报错
sudo umount -l /data
-f 强制卸载 (Force)
主要用于断开失效的网络文件系统(如已挂掉的 NFS / CIFS 共享服务)。
sudo umount -f /mnt/nfs
-R 递归卸载 (Recursive)
卸载指定的目录及其下挂载的所有子目录树。
sudo umount -R /mnt
  • 解决 umount: /data1: target is busy.
1
2
3
4
5
[root@router ~]# fuser -v /data1
USER PID ACCESS COMMAND
/data1: root kernel mount /data1
root 1633 ..c.. bash
[root@router ~]# fuser -km /data1
  • 永久挂载/卸载配置

编辑 /etc/fstab,末尾添加一行

字段序号 字段名称 推荐填写的数值/格式 说明与运维建议
第 1 列 设备标识 (Device) UUID="a1b2c3d4-..."LABEL="rhcsa" 强烈推荐使用 UUID(通过 blkid 获取),防止盘符重排序(如 /dev/sdb/dev/sdc
第 2 列 挂载点 (Mount Point) /data 必须为系统中的绝对路径,如果目录不存在需提前 mkdir
第 3 列 文件系统类型 (Filesystem) xfs / ext4 / vfat 必须与 blkid 查询到的真实文件系统类型一致,否则开机报错
第 4 列 挂载选项 (Mount Options) defaultsdefaults,noatime,noexec 通常填 defaults;如有安全性或性能优化需求可加额外选项
第 5 列 Dump 备份标志 0 0 表示不进行 dump 备份,1 表示备份(现代 Linux 几乎统一填 0
第 6 列 fsck 自检顺序 0 (XFS 填 0,EXT4 非根分区填 2) 0 为不检查,1 留给根分区 /2 为其他从分区。XFS 自身有日志修复机制,统一填 0

swap 交换分区/交换文件

步骤 操作阶段 创建 Swap 分区命令 创建 Swap 文件命令 作用解析与核心参数说明
1 分配存储空间 sudo fdisk /dev/sdb
(新建分区并按 t 修改 Type 代码为 82)
sudo fallocate -l 2G /swapfile
(或 sudo dd if=/dev/zero of=/swapfile bs=1M count=2048)
划定专用的存储空间。
分区方式写在分区表;文件方式直接在根分区下生成 2GB 大文件。
2 安全权限控制 (物理分区无需此步骤) sudo chmod 600 /swapfile 文件方式必做
限制 Swap 文件权限为仅 root 可读写(rw-------),防止普通用户读取内存敏感数据。
3 格式化 Swap sudo mkswap /dev/sdb2 sudo mkswap /swapfile 初始化元数据,写入 Swap 专属的文件系统标头与标志位。
4 启用(挂载)Swap sudo swapon /dev/sdb2 sudo swapon /swapfile 将 Swap 激活并挂载至当前内核,使其立即生效。
5 状态验证 swapon --show
(或 free -h)
swapon --show
(或 free -h)
查看 Swap 是否挂载成功、容量及使用的优先级(Priority)。
6 配置开机自动挂载 编辑 /etc/fstab 追加:
/dev/sdb2 none swap defaults 0 0
编辑 /etc/fstab 追加:
/swapfile none swap defaults 0 0
写入配置文件,确保系统重启后自动重新挂载并启用该 Swap 空间。

文件系统检查和修复

操作阶段 核心命令与实操指南 作用解析与核心参数说明
安全卸载目标分区 umount /dev/sdb1
(若 Busy:fuser -mv /dev/sdb1 杀进程或加 -l 卸载)
绝不能对已挂载的分区进行修复!直接修复读写状态的分区会导致文件系统元数据彻底损坏,造成二次破坏。
修复 EXT4 文件系统 e2fsck -fy /dev/sdb1
(或 fsck.ext4 -fy /dev/sdb1)
EXT4 专属工具
-f:强制检查(即便标记为 Clean);
-y:对所有自动修复提示默认回答 “yes”,无需手动交互确认。
修复 XFS 文件系统 xfs_repair /dev/sdb1
(若日志损坏:xfs_repair -L /dev/sdb1)
XFS 专属工具(注意:XFS 没有 fsck.xfs 实体功能)。
-L清空元数据日志(当日志损坏导致无法修复时使用,可能会丢失最近未落盘的数据,属最后手段)。
通用前端调用(备选) fsck -fy /dev/sdb1 通用前端命令
fsck 会自动读取设备的文件系统类型,并自动调用后台对应的 fsck.ext4xfs_repair
重新挂载与验证 mount -a
然后执行:df -hT /dev/sdb1
修复完成后,重新挂载分区并检查挂载状态与文件读写是否恢复正常。

LVM 逻辑卷管理

LVM 架构

graph TD
    subgraph 物理存储层 [物理存储层 Physical Storage]
        sda1[物理分区 /dev/sda1]
        sdb1[物理分区 /dev/sdb1]
        sdc[整块物理磁盘 /dev/sdc]
    end

    subgraph LVM_PV [物理卷层 Physical Volumes]
        pv1[PV: /dev/sda1]
        pv2[PV: /dev/sdb1]
        pv3[PV: /dev/sdc]
    end

    subgraph LVM_VG [卷组层 Volume Group]
        vg[VG: vg_data <br> 将所有 PV 划分为最小存储单元 PE]
    end

    subgraph LVM_LV [逻辑卷层 Logical Volumes]
        lv1[LV: lv_root]
        lv2[LV: lv_home]
    end

    subgraph 文件系统层 [文件系统与挂载点]
        fs1[XFS / EXT4 文件系统 <br> 挂载至 /]
        fs2[XFS / EXT4 文件系统 <br> 挂载至 /home]
    end

    sda1 -->|pvcreate| pv1
    sdb1 -->|pvcreate| pv2
    sdc -->|pvcreate| pv3

    pv1 -->|vgcreate| vg
    pv2 -->|vgcreate| vg
    pv3 -->|vgcreate| vg

    vg -->|lvcreate| lv1
    vg -->|lvcreate| lv2

    lv1 -->|mkfs & mount| fs1
    lv2 -->|mkfs & mount| fs2

    classDef storage fill:#f9f9f9,stroke:#666,stroke-width:1px;
    classDef lvm fill:#e1f5fe,stroke:#0288d1,stroke-width:2px;
    classDef vgStyle fill:#fff3e0,stroke:#f57c00,stroke-width:2px;
    classDef fsStyle fill:#e8f5e9,stroke:#388e3c,stroke-width:1px;

    class sda1,sdb1,sdc storage;
    class pv1,pv2,pv3,lv1,lv2 lvm;
    class vg vgStyle;
    class fs1,fs2 fsStyle;

使用 LVM 逻辑卷

  • 查看状态
步骤 常用命令 核心参数 & 常用选项解析 典型示例 / 命令写法
查看 PV / VG / LV 状态 pvs
vgs
lvs
列出存储各层级的简要汇总信息。
-o:自定义输出列;
-a:显示未分配或未激活的设备。
pvs
vgs
lvs
扫描与刷新 LVM 缓存 pvscan
vgscan
lvscan
深度扫描系统底层块设备,识别或更新 LVM 元数据与缓存。
-v:显示详细的扫描过程与调试日志。
vgscan
查看详细配置与 PE 映射 pvdisplay
vgdisplay
lvdisplay
输出详细元数据,包括 PE 大小、UUID、分布路径等。 lvdisplay /dev/vg_data/lv_storage
查看文件系统与挂载状态 lsblk
df -hT
lsblk -f:查看块设备树状拓扑、UUID 及文件系统类型;
df -hT:查看已挂载 LV 的容量使用率和文件系统(XFS/EXT4)。
lsblk -f
df -hT
  • 创建和挂载
步骤 常用命令 核心参数 & 常用选项解析 典型示例 / 命令写法
1. 初始化物理卷 (PV) pvcreate 将物理磁盘或分区初始化为 PV。 pvcreate (多个)磁盘或分区
pvcreate /dev/sdb /dev/sdc1
2. 构建卷组 (VG) vgcreate 组合 PV 形成存储池。
-s:指定 PE 单元大小(默认 4M)。
vgcreate 卷组名 物理卷
vgcreate vg_data /dev/sdb
3. 划分逻辑卷 (LV) lvcreate 从 VG 切割分配 LV。
-L:按绝对容量(如 -L 20G);
-l:按 PE 数或百分比(如 -l 100%FREE);
-n:指定 LV 名称。
lvcreate -L 20G -n lv_storage vg_data
4. 格式化文件系统 mkfs.xfs
mkfs.ext4
在创建好的 LV 上建立文件系统。
• 逻辑卷设备路径:/dev/卷组名/逻辑卷名
mkfs.xfs /dev/vg_data/lv_storage
5. 临时挂载 mount 将 LV 挂载到指定目录(重启后失效)。 mkdir -p /data
mount /dev/vg_data/lv_storage /data
配置 /etc/fstab 自动挂载 blkid
nano /etc/fstab
将 LV 挂载信息写入配置文件,开机自动挂载。
步骤 1:用 blkid 获取 LV 的 UUID;
步骤 2:在 /etc/fstab 格式追加配置;
步骤 3:用 mount -a 验证配置正确性。
写入 /etc/fstab 的标准行
UUID="xxxx-xxxx-..." /data xfs defaults 0 0
(或用路径: /dev/vg_data/lv_storage /data xfs defaults 0 0)

测试语法
mount -a
  • 扩容和缩容
步骤 常用命令 核心参数 & 常用选项解析 典型示例 / 命令写法
1. 在线扩容 LV 和文件系统 lvextend 扩展 LV 容量并同步刷新文件系统(无需卸载,在线即时生效)。
-L <Size>:指指定扩容后的目标大小或增加量(如 -L 10G-L +5G)。;
-l +100%FREE:分配 VG 剩余的所有空闲空间;
-r / --resizefs:自动识别并刷新底层文件系统(XFS/EXT4),一步到位。
lvextend -L +10G -r /dev/vg_data/lv_storage
(或 lvextend -l +100%FREE -r /dev/vg_data/lv_storage)
2. 单独扩容文件系统 xfs_growfs resize2fs xfs_growfs /挂载目录:适用于 xfs
resize2fs /dev/卷组名/逻辑卷名:适用于 ext4
xfs_growfs /data
resize2fs /dev/vg_data/lv_storage
1. 缩减 LV 前卸载并强制自检 (仅限 EXT4) umount & e2fsck 绝对不能在线缩容!必须先卸载文件系统,并强行自检确保没有元数据错误。
-f:强制检查。
umount /data
e2fsck -f /dev/vg_data/lv_storage
2. 缩减文件系统大小 (仅限 EXT4) resize2fs 先缩文件系统,再缩 LV(次序绝对不能颠倒,否则数据毁灭)!
• 将文件系统缩小到指定目标容量。
resize2fs /dev/vg_data/lv_storage 10G
(缩小到 10G)
3. 缩减 LV 逻辑卷 (仅限 EXT4) lvreduce 缩减 LV 设备容量归还给 VG。
-L <Size>:指定缩减后的目标大小或缩小量(如 -L 10G-L -5G)。
(或直接用 lvreduce -L 10G -r-r 自动依次执行文件系统缩减)
lvreduce -L 10G /dev/vg_data/lv_storage

完成后重新挂载
mount /dev/vg_data/lv_storage /data
扩容或缩减卷组 VG vgextend vgreduce 将新的 PV 加入现有 VG 存储池,扩大总池容量;或者从现有 VG 存储池移除 PV。 pvcreate /dev/sdc
vgextend vg_data /dev/sdc
  • 迁移和卸载
步骤 常用命令 核心参数 & 常用选项解析 典型示例 / 命令写法
1. 移走坏盘/旧盘上的数据 pvmove 在线热迁移数据。将某个 PV 上的所有数据块(PE)实时转移到同一个 VG 内的其他空闲 PV 上,业务不中断。 pvmove /dev/sdb
(自动迁移至同 VG 空闲 PV)
pvmove /dev/sdb /dev/sdc
2. 安全剔除并移除旧 PV vgreduce & pvremove 数据迁移完成后,将旧 PV 从 VG 中移除并清理 LVM 标头元数据。 vgreduce vg_data /dev/sdb
pvremove /dev/sdb
1. 卸载文件系统 umount 彻底断开挂载,防止读写数据造成数据损坏。
(必须同步删除 /etc/fstab 中对应的自动挂载配置)
umount /data
2. 删除逻辑卷 (LV) lvremove 释放 LV 占用的空间并归还给 VG。
-f / --force:强制删除(跳过确认提示)。
lvremove -f /dev/vg_data/lv_storage
3. 销毁卷组 (VG) vgremove 彻底销毁整个存储池。
-f:强制删除(连同下属未清理的 LV 一并清除)。
vgremove -f vg_data
4. 清理物理卷 (PV) pvremove 清除底层磁盘的 LVM 标头元数据,恢复为普通物理盘。 pvremove /dev/sdb /dev/sdc
  • 备份和还原
步骤 常用命令 核心参数 & 常用选项解析 典型示例 / 命令写法
创建快照 lvcreate -s--snapshot):创建快照卷;
-L:指定快照分配容量(根据变更量设定);
-n:指定快照逻辑卷名称。
lvcreate -L 5G -s -n lv_data_snap /dev/vg_data/lv_data
快照手动扩容 lvextend 当快照 Data% 接近上限时手动追加空间。
-L +<size>:为快照增加指定容量。
lvextend -L +2G /dev/vg_data/lv_data_snap
快照自动扩容 vim /etc/lvm/lvm.conf 在配置文件中修改 snapshot 相关参数 snapshot_autoextend_threshold = 70:当快照空间使用率超过 70% 时,触发自动扩容
snapshot_autoextend_percent = 20:触发扩容时将自动追加当前 20% 的空间
还原/合并快照 lvconvert 将源 LV 恢复至快照创建时刻的状态。
--merge:合并快照至源卷(须先卸载源卷与快照卷,合并完成后快照自动销毁)。
umount /mnt/data
lvconvert --merge /dev/vg_data/lv_data_snap
删除快照 lvremove 清除不再需要的快照,释放 VG 物理扩展(PE)空间。
-f:强制删除(无需交互确认)。
umount /mnt/snapshot
lvremove -f /dev/vg_data/lv_data_snap

存储与共享

NFS 共享存储

  • NFS 服务端(提供共享的服务器)
步骤 核心命令 / 修改的文件 核心参数与选项解析 典型示例 / 命令写法
安装服务 大多数 Linux 发行版中默认不自带(或仅自带客户端组件),通常需要手动安装 yum install nfs-utils -y
配置文件 /etc/exports 定义共享路径、允许访问的主机/网段及权限。
rw / ro:读写 / 只读权限;
sync:数据同步写入磁盘(保证一致性);
root_squash(默认) 将客户端 root 用户映射为服务端的匿名用户(通常为 nfsnobodynobody);
no_root_squash:保留客户端 root 用户权限(不降权为匿名用户);
all_squash:将所有访问客户端的用户(无论是 root 还是普通用户)统统映射为匿名用户。
no_all_squash(默认) 保持普通用户的 UID/GID 不变(按 UID 在服务端匹配对应用户)。
/data/share 192.168.1.0/24(rw,sync,no_root_squash)
服务管理 systemctl 启动 NFS 核心服务并设置开机自启。 systemctl enable --now nfs-server
动态刷新 exportfs 不重启服务即时加载或管理共享表。
-r:重新加载 /etc/exports 配置文件;
-v:显示当前导出的详细共享列表与权限;
-au:卸载所有导出的共享目录。
exportfs -rv
本地校验 showmount 查看本地生效的导出列表。
-e:显示导出(exports)列表。
showmount -e localhost
防火墙配置 firewall-cmd 放行 NFS 依赖的服务流量(nfs, rpc-bind, mountd)。 firewall-cmd --permanent --add-service={nfs,rpc-bind,mountd}
firewall-cmd --reload
  • NFS 客户端(使用共享的主机)
步骤 核心命令 / 修改的文件 核心参数与选项解析 典型示例 / 命令写法
探测共享 showmount 查询远端 NFS 服务器暴露的共享目录。
-e:指定远端服务器 IP 地址。
showmount -e 192.168.1.100
手动挂载 mount 临时/手动挂载远端 NFS 目录。
-t nfs:指定文件系统类型为 NFS。
mount -t nfs 192.168.1.100:/data/share /mnt/nfs_share
安全卸载 umount 卸载挂载点。
-l:延迟卸载(Lazy);
-f:强制卸载(针对服务端离线/连接卡死)。
umount -lf /mnt/nfs_share
永久挂载 /etc/fstab 配置开机自动挂载。
_netdev:指定必须等待网络就绪后再挂载(防止开机卡死)。
192.168.1.100:/data/share /mnt/nfs_share nfs defaults,_netdev 0 0
服务诊断 rpcinfo
nfsstat
rpcinfo -p:查看远端端口映射与 RPC 注册情况;
nfsstat -c:查看客户端 NFS 运行状态与性能统计。
rpcinfo -p 192.168.1.100
nfsstat -c

autofs 按需挂载

步骤 触发命令 / 配置文件变化 后台核心行为与机制解析
1 安装服务
yum install autofs -y
安装 autofs 软件包,-y 免交互。
2 编辑主配置文件
echo "/mnt/nfs /etc/auto.nfs --timeout=60" >> /etc/auto.master
加载主规则
指定 /mnt/nfs 为 Autofs 监控的父目录;
指定 /etc/auto.nfs 为子配置文件(文件名任意);
--timeout=60 设定空闲 60 秒后自动卸载。
3 创建子配置文件
echo "docs -rw,soft,sync 192.168.1.100:/data/docs" > /etc/auto.nfs
定义具体映射
声明相对子目录 docs(即挂载到/mnt/nfs/docs);
- 后面为挂载参数 rw,soft,sync
远端 NFS 共享路径 192.168.1.100:/data/docs
echo "* -rw,soft,sync 192.168.1.100:/data/&" > /etc/auto.nfs 使用通配符自动批量挂载
NFS 服务器 192.168.1.100/data/ 目录下存在文件夹时,在客户端自动挂载为同名文件夹。
4 启动服务
systemctl enable --now autofs
注册伪挂载点
内核在 /mnt/nfs 挂载一个轻量级 autofs 伪文件系统开启监听。此时 df -h 看不到远端 NFS。

SELinux

查看和切换模式

操作类型 操作 命令作用与效果说明
查看模式 getenforce 快速查看:仅返回当前运行模式名称(Enforcing / Permissive / Disabled)。
sestatus 详细查看:显示当前模式、配置文件预设模式、策略名称(targeted)等信息。
临时修改 setenforce 0 切为宽容模式(Permissive):保留安全日志记录,但不再实际阻断任何违规操作。
setenforce 1 切为强制模式(Enforcing):恢复完整安全防护,违规操作将被直接拒绝并记录
永久切换模式 修改 /etc/selinux/config 文件 强制模式: SELINUX=enforcing
宽容模式:SELINUX=permissive
禁用模式:SELINUX=disabled
修改后需执行 reboot 重启生效。
⚠️ 若从 Disabled 切换到 Enforcing,需注意全盘重新打标(touch /.autorelabel)。

SELinux 标签系统

标签系统(在 SELinux 中正式称为 安全上下文 Security Context)是 SELinux 实现强制访问控制的基础。没有标签,SELinux 的所有规则就失去了作用对象。
类型(Type)是标签(Label/Security Context)中最核心的一部分,在 SELinux 的日常交流中,大家为了方便,经常把“类型(Type)”俗称为“标签”(比如“给这个文件打上 httpd_sys_content_t 标签”),但在底层逻辑上,它们是包含与被包含的关系。

完整标签(Context / Label):指 system_u:object_r:httpd_sys_content_t:s0 这一长串完整的字符串(包含 User、Role、Type、Level 4个维度)。
类型(Type):只是其中第 3 个位置上的那个名字(比如 httpd_sys_content_t)。

  • 文件标签
操作类型 核心命令 / 步骤写法 核心选项含义 作用原理与适用场景
查看文件标签 ls -Z <文件或目录>
ls -Zd <目录>
-Z--context):显示文件的 SELinux 安全上下文信息
-d--directory):仅显示目录本身的信息,而非展开其内容
属性检查:显示文件或目录的安全上下文(用户:角色:类型:敏感度)。
示例:ls -Z /var/www/html
临时修改
(重打标或全盘恢复后失效)
chcon -R -t <类型> <文件或目录> -R--recursive):递归处理目录及其下的所有子文件与子目录
-t--type):指定要修改的目标 SELinux 类型(Type)
快速调试/排错:直接修改文件系统节点上的安全上下文。
示例:chcon -R -t httpd_sys_content_t /webdata
永久修改
(标准规范)
步骤 1(写数据库):
semanage fcontext -a -t <类型> "<文件或目录>"

步骤 2(刷新文件):
restorecon -Rv <文件或目录>
semanage 选项:
fcontext:管理文件上下文映射规则
-a--add):添加自定义映射规则
-t--type):指定映射规则中的目标类型
"(/*)?":正则表达式,匹配该目录及其下所有子路径

restorecon 选项:
-R / -r:递归刷新目录及其子项
-v:显示修改过程中的详细信息
生产与考试规范:先将映射关系存入 /etc/selinux 策略数据库,再应用到物理文件。
示例:
semanage fcontext -a -t httpd_sys_content_t "/webdata(/.*)?"
restorecon -Rv /webdata
规则查询/删除 • 查询:semanage fcontext -l | grep "<文件或目录>"
• 删除:semanage fcontext -d "<文件或目录>"
-l--list):列出数据库中所有的文件上下文定义
-d--delete):删除指定的自定义映射规则
用于检查数据库中已有的路径标签定义,或清除不再需要的自定义映射规则。
  • 进程标签
操作类型 核心命令 / 步骤写法 核心选项含义 作用原理与适用场景
查看运行进程标签 ps -efZ | grep <进程名> -e--everyone):显示所有进程
-f--full):列出进程的详细字段信息
-Z--context):显示进程的安全上下文(包含用户:角色:类型:灵敏度)
运行状态核查:查看系统当前正在运行进程的 SELinux 域名(Domain,如 httpd_t)。
示例:ps -efZ | grep httpd
查看进程文件标签 ls -Z <可执行文件路径> -Z--context):显示文件或目录的安全上下文 起点排查:查看二进制可执行文件自身的类型(如 httpd_exec_t),决定了进程启动时能否成功转换到目标 Domain。
示例:ls -Z /usr/sbin/httpd
修改二进制文件标签
(修改进程启动源)
semanage fcontext -a -t <文件类型> "<文件路径>"
restorecon -v <文件路径>
semanage fcontext -a:添加文件上下文默认规则
restorecon -v:根据策略库将新标签应用到实际文件
自定义程序放行:当从非标准路径(如 /opt/bin/)启动服务时,修正其二进制文件类型,使其启动时能正常触发 SELinux 域转换(Domain Transition)。
示例:semanage fcontext -a -t httpd_exec_t "/opt/myweb/bin/httpd"
手动指定域运行
(调试/测试场景)
runcon -t <域类型> <命令> -t--type):临时指定命令运行时的 SELinux 域类型(Domain) 调试与安全隔离:在特定安全域下运行一次性命令或测试程序,不改变系统全局策略,通常用于权限测试。
示例:runcon -t httpd_t /tmp/test_script.sh
  • 端口标签
操作类型 核心命令 / 步骤写法 核心选项含义 作用原理与适用场景
查看端口标签 semanage port -l
semanage port -l | grep <协议/端口/服务>
-l--list):列出数据库中所有已定义的端口安全上下文映射关系 映射查询:查看所有网络端口(TCP/UDP)与 SELinux 端口类型(如 http_port_tssh_port_t)的关联。
示例:semanage port -l | grep http_port_t
添加端口标签
(永久修改)
semanage port -a -t <端口类型> -p <协议> <端口号> -a--add):添加自定义端口映射规则
-t--type):指定目标端口 SELinux 类型(Type)
-p--proto):指定传输层协议(tcpudp
非标端口放行:当服务修改为非默认端口(如 Web 改为 8888、SSH 改为 22222)时,将新端口写入策略库,允许对应进程绑定。
示例:semanage port -a -t http_port_t -p tcp 8888
修改端口标签
(修改已有规则)
semanage port -m -t <端口类型> -p <协议> <端口号> -m--modify):修改已被定义的端口映射规则,重定向到新的类型 重定向类型:修改已被分配给其他类型的端口定义。
示例:semanage port -m -t ssh_port_t -p tcp 22222
删除端口标签
(清除自定义规则)
semanage port -d -t <端口类型> -p <协议> <端口号> -d--delete):删除指定的自定义端口映射规则 规则清理:移除不再需要的自定义端口绑定规则,恢复默认配置。
示例:semanage port -d -t http_port_t -p tcp 8888

SELinux 类型强制

在 SELinux 的安全架构中,类型强制(Type Enforcement, 简称 TE) 是其最核心的访问控制机制。而在 TE 机制下,布尔值(Booleans) 相当于一个 “动态控制开关系统”,它极大地提升了 SELinux 策略管理的灵活性与可运维性。

功能类型 核心命令 / 步骤写法 核心选项含义 作用原理与适用场景 对应命令的作用与区别
查询布尔值 getsebool -a
getsebool <布尔值>
-a--all):列出当前系统中所有已定义的布尔值及其当前运行状态 轻量排查:只从内核内存中读取当前的 on/off 状态,不包含额外说明,适合脚本调用或快速验证。 getsebool:只读查询工具,输出极简,速度最快。
区别:对比 semanage,它无法查看功能描述(Description)和磁盘默认状态。
查询布尔值 semanage boolean -l | grep <关键字> -l--list):列出布尔值名称、当前状态、默认状态及功能描述(Description) 文档查阅:从策略数据库中读取布尔值信息,提供完整的文字说明,用于不确定某个开关具体作用时查阅。 semanage boolean:综合管理/文档工具,信息最丰富。
区别:对比 getsebool,它能带出官方功能解释,便于定位未知开关。
修改布尔值 setsebool [-P] <布尔值> <on|off> -P--persistent:同步写入磁盘策略库,实现重启后永久生效(不加 -P 仅临时修改内存) 常用开关:直接通过内核接口修改内存/策略,语法直观且执行速度极快(1~3 秒),是运维与考试的首选。 setsebool:专属控制工具,默认仅修改内存(需显式加 -P 持久化)。
区别:相比 semanage,执行效率极高、参数简单好记。
修改布尔值 semanage boolean -m <--on|--off> <布尔值> -m--modify):修改策略库中的默认布尔值规则 策略重构:修改 SELinux 本地策略存储库并触发后台重新编译,天然实现永久生效(无需类似 -P 参数)。 semanage boolean:高层抽象管理入口,默认直接写入磁盘策略。
区别:相比 setsebool,需要调用 Python 引擎重编策略,耗时较长(3~8 秒)。

SELinux 的日志

默认情况下SElinux产生的日志是不会记录到 rsyslog 或者 journald 日志中,通过安装 setroubleshoot-server 服务将 SELinux 的日志转换到 rsyslog 或者 journald 以增强日志可读性。

1
2
3
4
5
yum install -y setroubleshoot-server
# 在 journalctl 中查看 SELinux 相关的友好日志
journalctl -t setroubleshoot --since "5 min ago"
# 或者在 /var/log/messages 中查看
grep "setroubleshoot" /var/log/messages

管理防火墙

iptablesfirewalld 本质上都是用户态的“管理客户端/前端工具”,它们真正控制的都是 Linux 内核底层的同一个防火墙框架——Netfilter。

iptables 工具

iptables 是 Linux 系统中最经典、影响最深远的包过滤防火墙管理工具。

虽然在 RHEL 8/9、Ubuntu 20.04+ 等现代 Linux 发行版中,默认的防火墙管理前端已经逐渐切换为 nftables 或 firewalld,但 iptables 的架构模型(表、链、规则)依然是理解 Linux 网络数据包流转、Docker 容器网络隔离以及 Kubernetes CNI 网络插件的基石。(仅作了解)

通过 Cockpit Web 页面管理

Cockpit 本身并不具备防火墙过滤算法,也不直接编写内核规则。
当登录 Cockpit 的网页界面,在“防火墙(Networking / Firewall)”菜单下点击“添加服务”或“开放端口”时,后台默默调用的就是 firewalld 的 API 或命令(firewall-cmd),firewalld 再去更新内核底层的 Netfilter / nftables 规则。

1
2
3
4
5
6
7
# 安装 Cockpit
yum install -y cockpit
# 启动服务并设置为开机自启
systemctl enable --now cockpit.socket
# 放行 cockpit 预定义服务(即 9090 端口)
firewall-cmd --permanent --add-service=cockpit
firewall-cmd --reload

访问 http://<服务器IP地址>:9090 来管理 Linux。

firewalld 工具

分类 核心命令写法 作用与实用场景
状态与查询 firewall-cmd --state 查看防火墙运行状态(running / not running)。
firewall-cmd --get-active-zones 查看当前生效的 Zone 以及分别绑定的网卡或 IP。
firewall-cmd --list-all 最高频:查看默认 Zone 内当前生效的所有规则。
firewall-cmd --get-services 查看系统预定义了哪些服务名(如 nfs, ssh, http)。
Zone 管理 firewall-cmd --set-default-zone=<zone> 更改系统的默认 Zone(如改为 internalwork)。
firewall-cmd --permanent --zone=<zone> --change-interface=<eth> 将网卡(如 eth0)永久绑定到指定 Zone。
firewall-cmd --permanent --zone=<zone> --add-source=<ip/mask> 将特定 IP/网段(如 10.0.0.0/24)绑定到指定 Zone。
放行/拒绝 firewall-cmd --permanent --add-service=<service> 按服务放行:永久允许指定服务(如 --add-service=nfs)。
firewall-cmd --permanent --add-port=<port/proto> 按端口放行:永久允许特定端口(如 --add-port=8080/tcp)。
firewall-cmd --permanent --remove-service=<service> 移除已放行的服务。
地址伪装
(NAT)
firewall-cmd --permanent [--zone=<zone>] --add-masquerade 开启地址伪装:允许内部私有 IP 通过本机的外网卡转换上网(路由器 SNAT),也是跨网段端口转发的先决条件
firewall-cmd --permanent [--zone=<zone>] --remove-masquerade 关闭(指定 Zone 的)地址伪装功能。
firewall-cmd [--zone=<zone>] --query-masquerade 查询(指定 Zone)是否已经开启地址伪装(输出 yesno)。
端口转发
(DNAT)
firewall-cmd --permanent [--zone=<zone>] --add-forward-port=port=<源端口>:proto=<协议>:toport=<目标端口> 本地端口重定向:将访问本机的“源端口”流量转发到本机的“目标端口”(例如将 8888 转到本地 80)。
firewall-cmd --permanent [--zone=<zone>] --add-forward-port=port=<源端口>:proto=<协议>:toport=<目标端口>:toaddr=<目标IP> 跨机器端口转发:将访问本机的流量转发到后端其他服务器的 IP 和端口(如将外部访问本机的 8080 转给内网 192.168.1.100:80)。需先开启伪装
firewall-cmd --permanent [--zone=<zone>] --remove-forward-port=port=<源端口>:proto=<协议>:toport=<目标端口>[:toaddr=<目标IP>] 删除已配置的本地或跨机器端口转发规则。
持久化生效 firewall-cmd --reload 必做:重载防火墙,让所有 --permanent 规则立刻生效。
firewall-cmd --runtime-to-permanent 将当前内存中临时试用的规则直接转存为永久规则
  • zone 包含的规则配置项
配置项(Key) 值类型 / 语法格式 作用与含义
target default:取决于该 Zone 配置文件底层定义的默认行为(通常等同于 REJECTDROP
ACCEPT:放行所有未匹配的包
DROP:丢弃所有未匹配的包
REJECT:拒绝所有未匹配的包
%%REJECT%%:使用 firewalld 全局配置中指定的默认拒绝方式
默认拒绝/放行动作:当数据包不匹配当前 Zone 里的任何规则时,最终执行的操作。
icmp-block-inversion no(默认:仅阻断列表内的类型)
yes(反转:仅放行列表内的类型)
ICMP 阻断反转开关:开启后,icmp-blocks 的逻辑由“黑名单”翻转为“白名单”。即阻断所有 ICMP 类型,只允许 icmp-blocks 里列出的类型
interfaces 网卡接口名称列表(空格分隔) 绑定的网卡接口:当前 Zone 所托管的物理或虚拟网卡。
sources IP 地址、CIDR 网段或 MAC 地址 绑定的来源 IP/网段:匹配这些来源流量并强制使用本 Zone 规则(优先级高于 interfaces)。
services 服务名称列表(定义在 /usr/lib/firewalld/services/ 下) 预定义服务放行:通过服务名快速放行其对应的一组默认端口。
ports 端口号/协议起始端口-结束端口/协议 按端口放行:手动指定开放的具体 TCP/UDP 端口(绕过服务名定义)。
protocols 网络协议名称(定义在 /etc/protocols 中) 按协议放行:放行指定的网络层/传输层协议流量。
masquerade yes | no IP 伪装(NAT/SNAT):是否开启源地址转换,常用于将本 Zone 作为网关或路由器出口。
forward-ports port=源端口:proto=协议:toport=目标端口:toaddr=目标IP 端口转发:将发往当前 Zone 指定端口的流量重定向到本地其他端口或远程 IP。
source-ports 端口号/协议 按来源端口放行:根据客户端(发起方)的源端口号放行流量(使用较少)。
icmp-blocks ICMP 类型名称列表 ICMP 阻断/放行:显式禁止或允许响应的 ICMP 类型。
rich rules 结构化字符串(Rich Language 标准语法) 富规则(复杂规则):支持将源 IP、端口、服务、日志及动作组合配置的高级规则。

Podman 容器

镜像管理

操作类型 核心命令写法 解析与实用场景
登录仓库 podman login <镜像仓库地址> 参数-u(用户名)、-p(密码)。
场景:登录私有或企业镜像仓库(如 Harbor、Quay.io)。凭据在 Rootless 模式下保存在 ~/.config/containers/auth.json,Root 模式下保存在 /run/containers/0/auth.json
登出仓库 podman logout <镜像仓库地址> 参数:无。
场景:清除本地保存的指定仓库认证 Token,防止凭据残留。
搜索镜像 podman search <关键字> 参数--limit <N>(限制返回结果条数)。
场景:在全局配置的镜像仓库列表(如 Docker Hub、Quay)中检索开源或公共镜像。
列出镜像 podman images
(或 podman image ls)
参数-a(显示包含中间层的所有镜像)、-q(仅输出 Image ID)。
场景:查看本地已存在的所有镜像列表、标签(TAG)、镜像 ID 与占用体积。
查看镜像 podman inspect <镜像ID/名称> 场景:查看镜像底层元数据,如默认环境变量、暴露端口、预设入口点(ENTRYPOINT)等。
拉取镜像 podman pull <[仓库地址/]镜像名[:TAG]> 参数:例 podman pull quay.io/centos/centos:stream9
场景:从远程仓库下载指定镜像。若不写仓库前缀,会自动依据 /etc/containers/registries.conf 的配置顺序搜索。
编译镜像 podman build -t <镜像名:TAG> . 参数-t(指定镜像名称与标签)、-f(手动指定 Dockerfile/Containerfile 路径)。
场景:读取当前目录下的 ContainerfileDockerfile 编译出自定义镜像。
导出镜像 podman save -o <镜像包.tar> <镜像名[:TAG]> 参数-o--output,指定导出的目标文件路径)。
场景:将本地镜像及其完整历史层归档打包为离线 .tar 文件,用于跨网络环境或无网环境分发。
导入镜像 podman load -i <镜像包.tar> 参数-i--input,指定导入的文件路径)。
场景:将离线打包的 .tar 镜像恢复载入到本地 Podman 镜像存储库中。
删除镜像 podman rmi <镜像ID/名称> 参数-f(强行删除,即使镜像正被现有容器依赖)。
场景:清理指定的单个或多个无用镜像。
清理镜像 podman image prune [-a] 参数-a(清理所有未被使用的镜像,而不仅是悬空镜像 dangling)。
场景:一键垃圾回收,清理无容器引用的残余镜像以释放磁盘空间。

容器部署

操作类型 核心命令写法 解析与实用场景
创建容器 podman run [网络/存储/端口选项] --name <容器名> -d <镜像名> 参数-d(后台运行)、--name(自定义容器名)、--rm(容器停止后自动删除物理文件)、-e(注入环境变量,如 -e MYSQL_ROOT_PASSWORD=123)。
场景:创建并启动容器的核心命令,常结合下方存储与网络选项组合使用。
进入交互
-it
参数-i--interactive 保持标准输入打开)、-t--tty 分配一个伪终端)。
场景:不加 -d 的话运行 podman run 后会立即进入容器内终端,可用于临时调试、一次性交互操作(退出即停止)。组合 -d 使用可以使容器保活。
临时容器
--rm
参数--rm:临时容器,用完即销毁。
场景:测试或调试完退出后, Podman 会自动删除该容器实例,不占用磁盘空间。
目录挂载
-v </宿主机路径|卷名>:/容器路径:Z
参数:Z(独占 SELinux 标签)、:z(多容器共享 SELinux 标签)、:ro(只读挂载)。
场景:直接将宿主机路径映射到容器(如 Web 目录 /opt/html)。在开启 SELinux 的系统上,必须:Z:z 尾巴,否则容器内部会报 Permission denied
桥接网络 (默认)
--net bridge (或不写)
解析:容器拥有独立的 IP 地址段,通过 Podman 虚拟网桥与外界打通。
场景:默认模式,安全隔离性最高。
主机网络
--net host
解析:容器与宿主机共享网络协议栈和 IP,无 NAT 转换开销。
场景:适用于高性能要求或需要直接监听宿主机网络端口的场景。注意:容器内监听端口会直接占用宿主机端口
容器共享网络
--net container:<已有容器ID/名称>
解析:与指定的另一个现有容器共享相同的网络命名空间(包括 IP 和 localhost)。
场景:常用于边车(Sidecar)模式或辅助调试工具容器与主容器通信。
端口映射
-p <宿主机端口>:<容器端口>[/协议]
参数:例 -p 8080:80(TCP端口)、-p 53:53/udp(UDP端口)、-p 127.0.0.1:3306:3306(仅限本地回环访问)。
场景:在 Bridge 模式下,通过系统 DNAT 将宿主机特定网卡端口流量重定向到容器内部对应的监听端口。
启停容器 podman start|stop|restart <容器ID/名称> 参数-t <秒数>(停止时的超时等待时间)。
场景:手动开关或重启已存在的容器。
列出容器 podman ps 参数-a(列出所有状态的容器,包含已退出的 Exited 容器)。
场景:查看容器当前的运行状态、映射端口与运行时长。
查看对象 podman inspect <容器|镜像|Pod|存储卷|网络> 参数-f <字段>--format 使用 Go 模板语法直接抓取指定字段)。
场景:查看对象的完整配置信息,包含运行时状态、环境变量、网络 IP 地址、挂载卷路径、资源限制等全部细节。
删除容器 podman rm [-f] <容器ID/名称> 参数-f(强行 Kill 正在运行的容器并直接清理)。
场景:物理删除一个或多个容器。
命名卷管理 podman volume create|ls|inspect [卷名] 子命令create(新建卷)、ls(列出卷)、inspect(查看卷)
场景:由 Podman 统一管理的命名卷,屏蔽宿主机物理路径细节,适合数据库等重要数据的持久化存储(如 MySQL 数据目录)。
自定义网络 podman network create <网络名>
--net <网络名>
解析:基于 Podman 内置 DNS 创建独立网桥。
场景:属于同一个自定义网络的多个容器,可以直接通过容器名称互相域名解析和通信。
进入容器 podman exec -it <容器ID/名称> <命令> 参数-i(保持标准输入)、-t(分配伪终端 TTY)。
场景:进入正在运行的容器内部执行命令(如:podman exec -it my-web /bin/bashsh)。
查看日志 podman logs [-f] [--tail N] <容器ID/名称> 参数-f(实时追踪打印 Follow)、--tail N(仅显示最后 N 行)。
场景:查看容器内部应用程序打出的标准输出(stdout/stderr)日志,故障排查的核心工具。
查看状态 podman stats [<容器ID/名称>] 参数:无。
场景:动态实时查看容器的 CPU 占用率、内存使用量、网络 I/O 及磁盘 Read/Write 吞吐率。

无根容器与 systemd 集成

无根容器(Rootless Container) 指的是在不需要获取宿主机 root 权限(普通用户身份)下运行和管理的容器。

  1. 作为普通用户登录,不能从 root 用户通过 su - 切换;
  2. 普通用户默认只能绑定 ≥1024 的端口,挂载的目录需要有相应的权限;
  3. 普通用户执行 podman run --userns=keep-id(把宿主机当前普通用户的 UID 直接映射为容器内部相同的 UID)。

Root 容器只要容器在创建时指定了 --restart 策略,它就会在系统启动时被这个服务统一唤醒;
而无根容器需要借助 systemd 用户服务机制,把 Podman 容器包装成宿主机 systemd 管理的一个标准系统服务,这样普通用户也能实现容器开机自启。

步骤 命令行 作用说明 关键选项 / 参数解析
1. 启动容器 podman run -d --name my-web -p 8080:80 nginx 后台运行一个基于 nginx 镜像的无根容器 -d:后台隐式运行(Detached mode)。
--name my-web:指定容器名称为 my-web
-p 8080:80:将宿主机 8080 端口映射到容器内 80 端口。
2. 创建服务目录 mkdir -p ~/.config/systemd/user/ 创建用于存放当前用户级 systemd 服务配置文件的标准目录 -p:递归创建目录,若父目录不存在则一并创建,且已存在时不报错。
~/.config/systemd/user/:无根 systemd 用户服务的默认检索路径。
3. 生成并移动服务文件 podman generate systemd --name my-web --files --new
mv container-my-web.service ~/.config/systemd/user/
读取容器配置自动生成 .service 文件,并将其移入用户级 systemd 目录 --name my-web:声明要为其生成配置的容器名称。
--files:将配置输出为文件(生成 container-my-web.service)而非打印到标准输出。
--new:指示 systemd 在服务启动/停止时使用全新创建和销毁容器的方式(podman run/rm),提高可靠性。
mv:移动文件至 step 2 创建的配置路径。
4. 注册并启动服务 systemctl --user daemon-reload
systemctl --user enable --now container-my-web
让 systemd 重载用户配置,随后开启该服务的开机自启并立即启动 --user:以当前普通用户上下文管理 systemd 服务(区别于系统级的 sudo systemctl)。
daemon-reload:重新扫描并加载配置文件变更。
enable:配置服务在系统启动(或用户 Session 激活)时自动运行。
--now:在设置 enable 的同时,立即触发 start 启动服务。
5. 开启用户保活 (Linger) loginctl enable-linger <user>
(需管理员或 sudo 权限执行)
开启指定用户的 Linger 机制,允许其 systemd 用户服务在无 SSH/Console 登录时依然后台自启并常驻 enable-linger:指示 logind 系统守护进程在宿主机开机时自动初始化指定 UID 的 systemd --user 服务树。
<user>:需要开启保活特性的目标用户名或 UID。

把容器做成 systemd 服务后,容器本质上依然是一个标准的 Podman 容器。常用的调试、日志查看、进入容器等命令均不受任何影响。但凡是涉及到改变容器运行状态(启动、停止、重启、删除)的操作,建议优先使用 systemctl --user,而不是 podman 命令。

管理需求 推荐使用的命令 为什么这么用?
日常排查/调试 podman logs / podman exec podman 的诊断命令功能更丰富,支持交互和即时日志。
控制开关/重启 systemctl --user <start|stop|restart> 由 systemd 统一接管生命周期,保持服务状态一致,避免误触发自动重启。
删除服务 systemctl --user disable --now container-my-web.service
rm -f ~/.config/systemd/user/container-my-web.service
systemctl --user daemon-reload
1. 停止服务并取消开机自启
2. 删除对应的 service 配置文件
3. 重新加载 systemd 配置,使其不再追踪该服务
看系统整体状态 systemctl --user status / journalctl --user 可以查看结合了宿主机事件、开机自启状态和容器输出的全局日志。

构建镜像

步骤阶段 命令行 / 文件 核心作用说明 关键选项与语法解析
1. 编写构建脚本 vim Containerfile
(或 Dockerfile)
用文本形式定义镜像的基础环境、安装依赖、文件复制及默认启动命令 具体字段详见下表
2. 执行镜像构建 podman build -t image-name:v1.0 . 读取 Containerfile 脚本,逐层执行指令并打包生成本地新镜像;
镜像名称可以只写镜像名称,也可以写完整的 域名/命名空间/镜像名称
-t my-custom-app:v1.0:为生成的新镜像打上名称与版本标签(<镜像名>:<Tag>)。
.:(不可忽略)指定构建上下文路径(Context),代表将当前目录下的文件提交给构建引擎。
3. 验证与测试 podman images
podman run --rm my-custom-app:v1.0
检查本地镜像库并运行临时容器,验证构建结果是否符合预期 podman images:确认新镜像已成功保存在本地存储树中。
podman run --rm:以临时交互或单次运行模式拉起新镜像,容器退出后自动清理,用于功能验证。
指令 (Instruction) 语法格式 核心作用说明 最佳实践 / 注意事项
FROM FROM <image>:<tag> 指定基础镜像,必须是第一条非注释指令 尽量指定具体 Tag(如 alpine:3.19),避免使用 latest 导致构建不确定。
RUN RUN <command> 在构建镜像时执行 Shell 命令并生成新的镜像层 建议用 && 合并多条命令(如 yum update && yum install -y ...),减少镜像层数与体积。
CMD CMD ["executable","param1"] 指定容器启动时的默认执行命令 可被 podman run 命令行参数覆盖。建议优先使用 Exec 格式(JSON 数组格式)。
ENTRYPOINT ENTRYPOINT ["executable"] 配置容器启动时固定的主进程入口 例如对于 ENTRYPOINT ["ping"] 的镜像,执行 podman run my-image 8.8.8.8 相当于容器内执行 ping 8.8.8.8
同时存在 CMD 时,会将 CMD 内容作为 ENTRYPOINT默认参数(会被用户参数覆盖)。
COPY COPY <src> ... <dest> 将宿主机本地文件/目录原样复制到镜像内部 相比 ADD 更透明安全。支持使用 --chown=<user>:<group> 自动修复宿主机文件属主。
ADD ADD <src> ... <dest> 增强版 COPY支持解压归档包与 URL 下载 自动解压 .tar.gz 等压缩包。除明确需要自动解压外,常规文件复制应优先选用 COPY
WORKDIR WORKDIR /path/to/workdir 为后续的 RUNCMDENTRYPOINT 设置工作目录 目录若不存在会自动创建。避免在 RUN 中写大量的 cd /dir,应统一用 WORKDIR 控制。
ENV ENV <key>=<value> 设置全局持久化环境变量 变量在构建期和容器运行时均有效。在 Containerfile 后续指令中可用 $KEY 引用。
USER USER <user>[:<group>] 切换后续指令及容器运行时的用户身份 (UID) Rootless 无根模式黄金字段!显式指定非 root 用户(如 USER 1001)提升容器安全性。
EXPOSE EXPOSE <port>[/<protocol>] 声明容器运行时监听的网络端口 仅起文档标识作用,不会真正开放宿主机端口(实际映射仍需在 podman run 时加上 -p)。
VOLUME VOLUME ["/path/in/container"] 声明容器内的某个目录为匿名数据挂载点 阻止写时复制(Copy-on-Write)对持久化性能的影响。构建时该目录下的修改在后续层不可逆。
LABEL LABEL <key>=<value> 为镜像添加自定义 KV 键值对元数据 用于标注维护者(maintainer)、版本号、组织架构或 Git Commit Hash 信息。