RHCSA 学习笔记(二):网络、Shell 脚本、SSH、高级权限与文件系统
学习红帽课程中的一些笔记,本系列共 3 篇,这是第 2 篇。
- RHCSA 学习笔记(一):命令行基础、用户权限、文本处理与进程管理
- RHCSA 学习笔记(二):网络、Shell 脚本、SSH、高级权限与文件系统(本篇)
- RHCSA 学习笔记(三):软件包、系统服务、存储管理、SELinux、防火墙与容器
网络基础和网络服务端口
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)。 - 注意:
1和0必须是连续的,不能交叉或交替出现。
- 前半部分全为
- 常见表达方式:
- 点分十进制:例如
255.255.255.0。 - CIDR 斜线记法:例如
/24,表示掩码的前 24 位全为1。
- 点分十进制:例如
子网掩码的作用
- 划分网络与主机区域:通过与 IP 地址进行**按位与(AND)**运算,提取出具体的网络地址。
- 判断同网段通信:设备在发送数据包前,通过对比目标 IP 与本地 IP 的网络地址:
- 相同:判定为同一局域网(同网段),直接通过 MAC 地址进行二层直连通信。
- 不同:判定为跨网段,需要将数据转发给默认网关(Router)进行三层路由。
- 划分子网与灵活规划:借助变长子网掩码(VLSM),可将大网段切分为多个较小的子网,减少广播域范围,提高网络安全与 IP 地址利用率。
默认网关
默认网关(Default Gateway)通常由跨网段出口设备(如路由器或三层交换机)担任,它是局域网设备通往其他外部网络(如其他子网或互联网)的“出入口”与“翻译官”。
- 物理实体:具备三层路由转发能力的网络设备接口(如家用路由器的 LAN 口 IP,或企业核心交换机的 VLAN 虚接口 IP)。
- 逻辑属性:
- IP 地址:必须与本地设备处于同一网段(例如本地 IP 为
192.168.1.100/24,网关通常设定为192.168.1.1或192.168.1.254)。 - MAC 地址:设备在进行跨网段通信时,数据包的目标 IP 保持不变,但二层目标 MAC 地址会指定为网关的 MAC 地址。
- IP 地址:必须与本地设备处于同一网段(例如本地 IP 为
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, eth2… wlan0, wlan1…
- 命名规则:以网络设备类型名称加上从 0 开始的递增数字标识,如
eth0、eth1、wlan0等。 - 运行机制:内核在系统引导启动时,按照硬件被探测到(Enumerated)的先后顺序依次分配编号。
- 存在问题:
- 不稳定与非确定性:多网卡环境下,当新增/移除网卡或 PCI 插槽顺序变更时,内核检测硬件的顺序可能发生变化,导致原先的
eth0在重启后变为eth1,引发网络配置失效。
- 不稳定与非确定性:多网卡环境下,当新增/移除网卡或 PCI 插槽顺序变更时,内核检测硬件的顺序可能发生变化,导致原先的
可预测命名方式:ens33, enp3s0, wlp2s0…
由 systemd / udev 引入的标准命名规则(Red Hat Enterprise Linux 7 及以上版本默认采用),旨在保证网卡名称在硬件变动或系统重启后始终保持绝对稳定。
- 命名前缀(表示设备类型):
en:以太网卡(Ethernet)wl:无线局域网卡(WLAN)ww:无线广域网卡(WWAN / 移动蜂窝网)
- 定位后缀(表示硬件物理位置/固件属性):
o<number>:板载设备(On-board),如eno1s<slot>:PCI 扩展插槽(Hotplug slot),如ens3p<bus>s<slot>:PCI 拓扑总线位置与插槽,如enp2s0x<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 默认的动态网络管理守护进程,能够自动感知网络状态变化,并提供nmcli、nmtui等丰富工具来统一、动态地配置和管理各种物理及虚拟网络连接。
| 章节与操作 | 工具 / 语法 | 核心功能与运行机制 | 实用操作示例 |
|---|---|---|---|
| 临时配置网络地址 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 | ip route add 10.0.0.0/24 via 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(设备) 代表系统内核识别到的物理或虚拟网卡硬件(例如
enp2s0、eth0、wlan0)。它仅对应网络通信的物理/逻辑载体,负责实际的数据包收发,体现的是硬件的状态(如是否插好网线、Link 状态是否正常),设备本身并不直接保存具体的网络参数。 - Connection(连接) 则是一套逻辑配置文件。它包含了网卡工作所需的所有静态/动态网络参数,例如 IP 地址、子网掩码、默认网关、DNS 服务器、MAC 地址绑定以及开机自动连接属性(
autoconnect)。这些配置文件持久化存储在系统的/etc/NetworkManager/system-connections/目录下。
nmcli connection 核心子命令列表
| 子命令 | 命令语法 | 核心功能与关键参数 | 实用示例 |
|---|---|---|---|
show |
nmcli c show [--active | <连接名>] |
查看网络连接。不加参数列出所有连接,指定名字显示详细配置。 • --active:仅列出当前激活的连接 |
nmcli c shownmcli c show --activenmcli c show eth0-static |
add |
nmcli c add type <类型> ifname <网卡名> con-name <连接名> [参数 值] |
新建连接并永久写入磁盘。 • type:网络类型(如 ethernet)• ipv4.method:manual(静态)或 auto(DHCP)• ipv4.addresses / ipv4.gateway / ipv4.dns:指定静态网络参数 |
nmcli c add type ethernet ifname enp2s0 con-name enp2s0-dhcpnmcli 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/24nmcli 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"):删除指定的某一条配置。
- 基础与通用参数
| 参数名 | 语法 / 取值范围 | 说明 |
|---|---|---|
connection.id |
自定义字符串 | 连接配置的名称(如 ens33) |
connection.interface-name |
硬件网卡名 | 绑定的物理或虚拟网卡名称(如 ens33、eth0) |
connection.autoconnect |
yes / no |
开机是否自动激活连接(默认 yes) |
connection.type |
ethernet / bridge / bond 等 |
连接类型(以太网、网桥、聚合链路等) |
- 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 | [root@lab ~]# ls /etc/NetworkManager/system-connections |
配置文件路径:/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
2systemctl restart NetworkManager
nmcli connection up xxxxx - 先
reload重新加载这个connection,然后进行up
1
2nmcli connection reload
nmcli connection up xxxx
- 先重启
网络 bond 技术
常见的网络高可用技术有两个:
bondteam
team 和 bond 作用是一样的,只不过现在比较主流的还是网络 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虚拟机的话,必须保证俩张物理网卡的网络模式都是一样的
配置步骤:
- 删除或者备份物理服务器的两张物理网卡的
connection配置文件 - 创建虚拟网卡设备
bond1,指定对应的connection配置文件,类型是bond``,connection名字叫做con-bond1,bond模式为active-backup主备模式
1 | [root@rhel9 ~]# nmcli connection add type bond con-name con-bond1 ifname bond1 mode active-backup |
- 将两张物理网卡加入到
bond1中,作为bond1的子接口
1 | [root@rhel9 ~]# nmcli connection add type bond-slave con-name bond1-eth0 ifname eth0 master bond1 |
- 修改虚拟网卡设备bond1的网络信息,要求IP地址是20.0.0.100/24,dns 223.5.55,网关 20.0.0.2
1 | [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 |
- 查看网络bond的状态
1 | [root@rhel9 ~]# cat /proc/net/bonding/bond1 |
虚拟化的网络模式
- 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([完成])
- 挂载对应的 ISO 镜像文件
- 在操作系统上挂载对应 ISO 到指定的目录中
1
mount /dev/sr0 /media
- 配置本地 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. - 安装软件包组
1
2[root@rhel9 ~]# yum groupinstall "Virtualization Host" -y
[root@rhel9 ~]# yum install virt-manager -y - 启动服务
1
[root@rhel9 ~]# systemctl start libvirtd.service
- 创建桥接网络
- 创建一个虚拟网卡设备
br0 - 将
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 | [root@rhel9 ~]# cat /etc/hosts |
如果配置了本地hosts文件解析,也配置了DNS服务器做解析,本地hosts文件优先级更高。
网络服务端口
监听端口如果是1024以下的,则这个服务必须是 root 用户启动。1024以下监听端口我们称之为特权端口。
监听端口是1024以上的,这个服务可以是普通用户启动页可以是 root 用户启动。1024以上的监听端口我们称之为非特权端口。
查看网络服务监听端口的命令工具:
ssnetstat
是因为查询网络监听效率的问题。对于操作系统上,如果有大量的监听情况,用 ss 的性能远远超过 netstat。
1 | 常用选项(ss 和 netstat 都可用): |
shell 脚本实践
shell 脚本编写规范
- 脚本文件的名称一定要以
.sh结尾,目的是为了别人知道这就是一个shell脚本 - 脚本文件的第一行内容要写上声明,声明用什么解释器去执行这脚本的内容
1
1
- 脚本中每一个命令要写上注释,表示这个命令是干什么使用的,注释符号使用#
单行注释:#
多行注释:<<EOF开头,EOF结尾1
2
3
4
5
6
<<eof
echo huawei123
echo redhat456
eof
echo root - 脚本内容一定要有缩进
执行脚本的方式
| 执行方式 | 示例命令 | 需要可执行权限 (+x)? |
运行进程环境 | 脚本变量能否影响当前终端? | 核心适用场景 |
|---|---|---|---|---|---|
| 使用相对路径或绝对路径直接执行 | ./script.sh |
是 | 子 Shell | 否 | 生产环境、常规脚本部署 |
| 显式指定 Shell 解释器执行 | bash script.sh |
否 | 子 Shell | 否 | 临时测试无权限脚本 |
使用 source 或 . 命令执行 |
source script.sh |
否 | 当前 Shell | 能 | 加载环境变量、刷新配置 |
| 提交给后台或计划任务静默执行 | nohup ./script.sh & |
是 | 后台子 Shell | 否 | 长时间运行的大任务/服务 |
位置参数
当在终端运行一个 Shell 脚本或者函数时,在命令后面跟上的那些参数,会按照“从左到右的位置顺序”自动赋值给一组预定义的参数(从 $1 开始,多位数的参数用 ${n} 表示)。这组参数就叫做位置参数。
1 | [root@rhel9 opt]# cat useradd.sh |
脚本结合 read 命令实现提示信息
read 命令,它的主要作用是从标准输入(通常是键盘输入,也可以是文件或管道)读取一行数据,并将其赋值给一个或多个变量。
-p选项可以指定提示信息(Prompt),编写脚本时多用此选项用来提示用户输入信息。-t超时时间,单位是s,超过了这个时间就会跳过这条read命令-s隐藏输入,从键盘上输入的信息不会显示出来
1 | [root@rhel9 opt]# read -p "Input username: " |
1 | [root@rhel9 opt]# cat useradd.sh |
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 |
将多条命令的输出统一重定向打包输出到文件。 |
条件与判断
条件测试语句
条件测试语句是用来判断条件是否为真或者为假,通常会应用到 if、cases 判断语句中以及 while 循环、until 循环语句中。
- 条件为真,返回值为0
- 条件为假,返回值为非0
- 格式1:
test 条件表达式多用于在终端上临时测试
1 | [root@rhel9 opt]# test 1 = 1 |
格式2:
[条件表达式]多用于 shell 脚本
[root@rhel9 opt]# [ 1 = 2 ]
[root@rhel9 opt]# echo $?
1
[root@rhel9 opt]# [ 1 = 1 ]
[root@rhel9 opt]# echo $?
0格式3:
[[ 条件表达式 ]]支持原生的逻辑与/或,支持通配符与正则匹配
1 | [root@lab ~]# [[ 1 = 1 && 2 = 2 ]] # && 表示需要同时满足才会输出 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 | [root@rhel9 opt]# df -h / | grep -oP '\d+(?=%)' |
字符串比较运算符
| 运算符 | 缩写 / 含义 | 详细功能说明 | 示例 |
|---|---|---|---|
= / == |
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 | if 条件表达式;then |
示例:判断文件是否存在
1 |
|
- 双分支结构:条件满足执行分支 A,不满足则执行分支 B。
1 | if 条件表达式;then |
示例:验证当前用户是否为root
1 |
|
- 多分支结构:用于排他性的多条件依次评估,只要遇到第一个成立的条件,后续分支全部忽略。
1 | if 条件表达式1;then |
示例:判断分数区间
1 |
|
case 判断
当需要对同一个变量匹配多个固定值(如菜单选择、启动脚本的 start/stop/restart)时,case 比叠加多个 elif 更加清晰简洁。
1 | case $变量 in |
示例:
1 |
|
循环语句
for 循环
1 | for 变量名 in 循环的值;do |
循环的值的多种表达方式:
| 语法类别 | 代码写法(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 |
|
while 循环
只要 while 指定的条件评估为“真”(Exit Status 为 0),就会一直重复执行循环体内的代码,直到条件变假(退出状态码非 0)或被手动中断为止。
1 | while 条件表达式/命令;do |
案例:创建新用户,用户名存在时要求重新输入
1 |
|
until 循环
while :只要条件成立(真),就一直做;直到条件不成立(假)才停止;until :只要条件不成立(假),就一直做;直到条件成立(真)才停止。
1 | until 条件表达式/命令;do |
案例:持续 ping 某服务器,一旦 ping 通(返回 0),条件变为“真”,立即跳出循环继续执行后续脚本。
1 |
|
中断语句
continue 跳过本次
当需要遍历一批对象,但想过滤掉其中某些不合规项时,使用 continue 跳过此次循环,进行下一次的循环。
1 |
|
break 中断循环
当目的已经达到(如找到了所需文件)或遇到不需要再继续的条件时,使用 break 跳出循环。
break 只会中断并跳出它所在的那一层(最内层)循环,外层的循环依然会继续正常执行。
1 | [root@rhel9 opt]# cat break.sh |
计划任务
一次性计划任务 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
3at -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.hourly、cron.daily、cron.weekly、cron.monthly,将脚本放置在对应的文件夹中,就会对应时间定期执行脚本。
其中 etc/cron.hourly 下的脚本是由 /etc/cron.d/0hourly 每小时触发运行的:
1 | [root@lab ~]# cat /etc/cron.d/0hourly |
etc/cron.hourly 下默认有一个 0anacron 脚本,作用是每小时拉起 anacron,如果今天已经跑过了则跳过。
anacron 通过读取 /etc/anacrontab 配置文件,会每隔固定时间分别运行 cron.daily、cron.weekly、cron.monthly 下的所有脚本:
1 | [root@lab ~]# cat /etc/anacrontab |
调用链图解:
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 个文件(0hourly、0daily、0weekly、0monthly)让crond直接跑?这源于传统
crond的一个致命缺陷:
- ❌ 传统
crond的死穴:如果把cron.daily设置在每天凌晨 02:00 运行,但如果这台机器是个人笔记本或桌面 PC,晚上 02:00 恰好关机休眠了。那么当第二天早上开机时,02:00 已经过去,今天的daily任务就被静默跳过了!如果机器一直晚上关机,日任务和周任务将永远无法执行。为了解决这个问题,现代 Linux 引入了
anacron(Anachronistic Cron,意为“打破时间顺规的 Cron”):
anacron的优势:它不依赖“在精确的某个时间点必须开机”。它靠文件记录上一次运行的时间戳。开机后只要 crond(通过 0hourly)唤醒了anacron,anacron发现“昨天/上周的任务还没跑”,就会在开机几分钟后把漏掉的任务补跑一遍。为什么
cron.hourly不使用anacron补跑?每小时任务(Hourly)“补跑”没有实际意义。
anacron设计的核心哲学是:“补跑那些即使延迟几小时执行,依然有价值的任务”(比如每天日志切割、每周数据库索引优化)。
但对于按“小时”单位运行的任务,补跑往往是毫无意义甚至是有害的:
- 时效性极强:每小时任务通常是做清理 /tmp 临时文件、收集上一小时 CPU 指标等极短周期的动作。
因此,错过就错过,直接等待下一个整点(下一小时的第 01 分钟)再次触发,才是每小时任务最合理的逻辑。
文件查找工具
文件查找工具 locate
locate特点:
- 根据关键字搜索(模糊查找),只要文件名称包含这个关键字就可以搜索到;
- 根据数据库索引文件搜索,如果数据库的索引文件不存在则无法使用,需要执行
updatedb命令来更新数据库索引文件; locate不是实时查询,有可能有的文件明明存在但是无法查询到,要么就等待自己更新数据库索引,要么手动执行updatedb命令更新;- 所有查找工具共同的特点,查找的目录必须要有
r和x权限。
常用选项:
1 | -i 忽略关键字的大小写 |
文件查找工具 find
find特点:
- 实时查询文件,默认精确查询,也可以进行模糊查询(支持各种通配符);
find工具可以在查找到文件的基础之上执行二次命令操作(比如搜索系统上所有以.swp结尾的文件,然后去删除掉);find支持各种条件查询(根据文件名称查询文件、根据文件的 inode 编号查询文件、根据文件的权限查询文件、根据文件的拥有人/拥有组身份查询文件、根据文件的时间戳查询文件、根据目录的层级来查询文件…);- 所有查找工具共同的特点,查找的目录必须要有
r和x权限; - find查询的时候是遍历查询,所以速度较慢。
查询条件
| 查询维度 | 匹配参数 | 语法示例 | 详细解释与说明 |
|---|---|---|---|
| 文件名 | -name |
find . -name "*.log" |
按文件名匹配(区分大小写),查找所有 .log 结尾的文件 |
-iname |
find . -iname "test.txt" |
按文件名匹配(不区分大小写),可匹配 Test.txt 或 TEST.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 <命令> {} \; |
在执行后续命令前,对每个文件逐一询问提示(需输入 y 或 n 确认) |
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
4ssh -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 协议进行加密传输,但相比 scp,rsync 最大的优势在于增量传输(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 | [root@rhel9 ~]# getfacl /opt/ |
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, lisiHost_Alias WEBHOSTS = web1, web2Runas_Alias WEBOP = www-data, appuserCmnd_Alias WEB_CMD = /usr/bin/systemctl restart nginx, /usr/bin/systemctl reload nginxWEBDEV 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 <格式>:指定文件系统类型(如 ext4、xfs)• -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)直接进行压缩 |