第四周学习
1. 通过网络配置命令,让主机可以上网。 ip, netmask, gateway, dns,主机名。相关命令总结,最终可以通过这些配置让你的主机上网。
1.1 使用配置命令让主机可上网
# 关闭现在使用的网卡,添加一块新网卡进行配置
[root@rocky9-15 yum.repos.d]# ip link show ens160 #确认现在网卡已经关闭
2: ens160: <BROADCAST,MULTICAST> mtu 1500 qdisc mq state DOWN mode DEFAULT group default qlen 1000
link/ether 00:0c:29:a5:bf:17 brd ff:ff:ff:ff:ff:ff
altname enp3s0
# 新增一块网卡
3: ens224: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
link/ether 00:0c:29:a5:bf:21 brd ff:ff:ff:ff:ff:ff
[root@rocky9-15 ~]# ip addr add 10.0.0.111/24 dev ens224 #仅在当前终端生效
[root@rocky9-15 ~]# ip link set ens224 up #启动网卡
[root@rocky9-15 ~]# ip addr show ens224 | grep "inet"#验证网卡信息
inet 10.0.0.111/24 scope global ens224
[root@rocky9-15 ~]# ip route show | grep "default" #检查是否有默认路由
default via 10.0.0.2 dev ens160 proto static metric 100
[root@rocky9-15 system-connections]# ping www.baidu.com #测试联网
PING www.a.shifen.com (183.2.172.177) 56(84) 比特的数据。
64 比特,来自 183.2.172.177 (183.2.172.177): icmp_seq=1 ttl=128 时间=5.57 毫秒
64 比特,来自 183.2.172.177 (183.2.172.177): icmp_seq=2 ttl=128 时间=5.89 毫秒
64 比特,来自 183.2.172.177 (183.2.172.177): icmp_seq=3 ttl=128 时间=6.07 毫秒
#联网成功
1.2 使用配置文件让主机可上网
重启系统,清除手动设置的ip
[root@rocky9-15 ~]# ip add show ens224#检查是否存在
3: ens224: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
link/ether 00:0c:29:a5:bf:21 brd ff:ff:ff:ff:ff:ff
altname enp19s0
下面为一个网卡文件的主要内容
[connection]
id=my-ens224 # 连接的自定义名称
uuid=8d79afb0-1234-5678-90ab-cdef12345678 # 使用 `uuidgen` 生成的唯一标识符
type=ethernet # 连接类型为以太网
interface-name=ens224 # 绑定的物理网卡名称
autoconnect=true # 开机自动激活连接
[ethernet]
mac-address=00:11:22:33:44:55 # (可选)指定物理网卡 MAC 地址
[ipv4]
method=manual # 静态 IP 配置模式
addresses=10.0.0。111/24 # 静态 IP 地址及掩码
gateway=10.0.0.1 # 默认网关
dns=8.8.8.8,8.8.4.4 # DNS 服务器列表
dns-search=example.com # (可选)DNS 搜索域
[ipv6]
method=disabled # 禁用 IPv6
2. 解析/etc/sysconfig/network-scripts/ifcfg-eth0配置格式。
注:/etc/sysconfig/network-scripts/ifcfg-eth0 是centos7及更早版本使用的格式了,从后面的版本就改成了/etc/NetworkManager/system-connections文件夹下面了。但是centos8后面的版本仍然支持这个文件格式.
TYPE=Ethernet # 网卡类型为以太网
DEVICE=eth0 # 物理网卡名称
BOOTPROTO=static # IP分配方式(static/dhcp/none)
IPADDR=192.168.1.100 # 静态IP地址
NETMASK=255.255.255.0 # 子网掩码
GATEWAY=192.168.1.1 # 默认网关
DNS1=8.8.8.8 # 主DNS服务器
DNS1=8.8.8.8 # 备DNS服务器
ONBOOT=yes # 开机自动激活
HWADDR=00:0C:29:13:5D:74 # (可选)绑定MAC地址
USERCTL=no # 禁止非root用户控制
3. 基于配置文件或命令完成bond0配置
3.1、bond0 简介
bond0 的定义与核心特性
bond0 是 Linux 系统中用于 多网卡绑定(NIC bonding)的逻辑接口技术,通过将多个物理网卡聚合为一个虚拟接口,实现以下核心功能:
- 冗余备份:当某块物理网卡故障时,自动切换到其他可用网卡,保障网络高可用性
- 带宽扩容:通过多网卡并行传输数据,提升整体吞吐量(取决于绑定模式)
- 负载均衡:将网络流量分散到不同物理网卡,避免单点性能瓶颈
bond0 的工作模式
bond0 的实际行为由 绑定模式(mode)决定,常见模式包括:
- mode=0(balance-rr)
轮询(Round-Robin)策略,数据包依次通过各物理网卡发送,最大化带宽利用率,适合负载均衡场景 - mode=1(active-backup)
主备模式,仅主网卡处于活动状态,备份网卡在主网卡故障时接管,适合高可靠性需求 - 其他模式
如 mode=4(802.3ad,动态链路聚合)需交换机支持 LACP 协议
bond0 的典型应用场景
- 服务器高可用
数据库、文件服务器等需持续在线服务,通过 bond0 避免单网卡故障导致服务中断 - 网络带宽优化
视频流、大规模数据传输场景中,使用 mode=0 或 mode=4 提升吞吐性能 - 虚拟化环境
虚拟机或容器宿主机通过 bond0 提供稳定的底层网络连接
3.2 使用命令进行搭建bond0
3.2.1、环境准备
关闭VM仅主机模式的dhcp分配,添加两块新的网卡,选择仅主机模式

添加新网卡
eth3和eth4是我们新增的网卡
把新增的网卡激活下
nmcli device connect eth4 #激活eth4网卡
nmcli device connect eth3#激活eth3网卡
[root@openEuler-19 ~]# nmcli con
NAME UUID TYPE DEVICE
eth3 4c166a35-3580-4750-b684-62f943fa10ec ethernet eth3
eth4 5ac191ff-eb2d-4098-ab31-e38be9f47079 ethernet eth4
eth0 5fb06bd0-0bb0-7ffb-45f1-d6edd65f3e03 ethernet eth0
eth1 86692a40-9cd9-4893-8ea5-a63dfbdfb672 ethernet eth1
lo 161c12ae-267e-4af5-b43b-38b702cbd5a5 loopback lo
定制bond配置
[root@openEuler-19 network-scripts]# cat ifcfg-bond0
NAME=bond0
TYPE=bond
DEVICE=bond0
BOOTPROTO=none
IPADDR=192.168.8.122
PREFIX=24
BONDING_OPTS="mode=1 miimon=100 fail_over_mac=1"
定制网卡配置
[root@openEuler-19 network-scripts]# cat > /etc/sysconfig/network-scripts/ifcfg-eth3 <<-eof
NAME=eth3
DEVICE=eth3
BOOTPROTO=none
MASTER=bond0
SLAVE=yes
ONBOOT=yes
eof
[root@openEuler-19 network-scripts]# cat > /etc/sysconfig/network-scripts/ifcfg-eth4 <<-eof
NAME=eth4
DEVICE=eth4
BOOTPROTO=none
MASTER=bond0
SLAVE=yes
ONBOOT=yes
eof
重启网卡查看效果

cat /proc/net/bonding/bond0 查看是否成功绑定网卡

可以看到bond0的环境已经搭建完成
进行网络测试

确保只有我们的bond0网卡和bond0的绑定网卡再启动
可以看到在连通网络时,关闭了eth3网卡,另外一块备用网卡eth4会起作用,并没有流量异常。

4. 通过ifconfig命令结果找到ip地址.
ifconfig是我们net-tools扩展包里的一个命令,需要先安装net-tools
[root@rocky9-15 ~]# yum install -y net-tools
上次元数据过期检查:23:02:34 前,执行于 2025年05月25日 星期日 22时52分40秒。
软件包 net-tools-2.0-0.64.20160912git.el9.x86_64 已安装。
依赖关系解决。
无需任何处理。
完毕!
然后直接输入ifconfig即可查看我们网卡的ip地址

5. 使用脚本判断 你主机所在网络内在线的主机IP有哪些? ping通则在线。
#!/bin/bash
# 获取本机IP和网段
LOCAL_IP=$(hostname -I | awk '{print $1}')
NETWORK=$(echo $LOCAL_IP | cut -d'.' -f1-3)
# 扫描1-254范围IP
echo "扫描网段: ${NETWORK}.0/24"
for i in {1..254}; do
ip="${NETWORK}.${i}"
# 设置1秒超时,发送1个ICMP包
ping -c 1 -W 1 $ip > /dev/null 2>&1 && \
echo -e "\033[32m[在线]\033[0m $ip" || \
echo -e "\033[31m[离线]\033[0m $ip"
done
但是这个脚本有一些问题就是,假如我的子网并不是/24,可以是/16或者是/28;那这样的话,这个脚本实际就失效了
6. 使用while read line和/etc/passwd,计算用户id总和。
#!/bin/bash
total=0
# 逐行读取/etc/passwd文件
while IFS=: read -r username _ uid _; do
# 累加用户ID(第3个字段)
total=$((total + uid))
done < /etc/passwd
echo "系统所有用户ID总和为: $total"
7. 总结索引数组和关联数组,字符串处理,高级变量使用及示例。
7.1、索引数组
- 基础定义
- 通过整数下标访问元素(从0开始计数)
- 声明方式:
array=(value1 value2 value3)注意数据与数据之间是空格隔开 - 支持稀疏存储(非连续下标)
2、核心操作
[root@rocky9-15 week4]# array=(1 5 7 89 14) #定义一个数组
[root@rocky9-15 week4]# echo ${array[1]} # 输出第二个元素:5
5
[root@rocky9-15 week4]# echo ${array[@]} #输出全部元素
1 5 7 89 14
[root@rocky9-15 week4]# echo ${#array[@]} #获取数组长度
5
- 特殊用法
- 动态修改元素:
files[2]="newfile"
[root@rocky9-15 week4]# array[1]=666 #将5改为666
[root@rocky9-15 week4]# echo ${array[1]} # 输出第二个元素:666
666
-
获取所有索引:
${!files[@]}(适用于稀疏数组)[root@rocky9-15 week4]# array[10]=9999 #将数组第11个元素赋值为9999,在shell的数组是允许下标索引不连续的,所以我们可以直接中间索引直接直接给索引11直接赋值的,这样的话我们的数组就变成了一个稀疏数组。 [root@rocky9-15 week4]# echo ${!array[@]} 0 1 2 3 4 10 -
切片操作:
${files[@]:1:2}(从索引1开始取2个元素)[root@rocky9-15 week4]# echo ${array[@]:1:2} 666 7
7.2、关联数组
1、定义
在Bash中,关联数组(Associative Array)是一种以字符串作为键(而非数字索引)的键值对数据结构,类似于其他语言中的字典(Dictionary)或映射(Map)。
2、 声明关联数组
必须使用 declare -A 显式声明,否则会被视为普通数组
[root@rocky9-15 week4]# declare -A personMap # 声明一个关联数组
3、初始化与赋值
[root@rocky9-15 week4]# personMap=( [name]="test" [age]=23 [city]="GUANZHOU" ) #赋值
[root@rocky9-15 week4]# echo ${personMap[name]}
test
[root@rocky9-15 week4]# personMap[sex]="nan" #动态赋值
[root@rocky9-15 week4]# echo ${personMap[sex]}
nan
[root@rocky9-15 week4]# for key in "${!personMap[@]}";do #遍历键值对
> echo "Key:$key,Value:${personMap[$key]}"
> done
Key:city,Value:GUANZHOU
Key:age,Value:23
Key:sex,Value:nan
Key:name,Value:test
4、删除元素
[root@rocky9-15 week4]# unset personMap[age] #删除键为age的条目
[root@rocky9-15 week4]# echo ${personMap[age]}
7.3、字符串处理
字符串截取

[root@rocky9-15 ~]# string=abc12342341
[root@rocky9-15 ~]# echo ${string#a*3} #删除abc123子串,保留42341
42341
[root@rocky9-15 ~]# echo ${string#c*3} #匹配不到子串,输出全部
abc12342341
[root@rocky9-15 ~]# echo ${string#*c1*3} #匹配abc123子串,输出全部42341
42341
[root@rocky9-15 ~]# echo ${string##a*3} #匹配abc123423子串,输出全部41
41
[root@rocky9-15 ~]# echo ${string%3*1} #匹配341子串,输出abc12342
abc12342
[root@rocky9-15 ~]# echo ${string%%3*1} #匹配342341子串,输出abc12
abc12
字符串截取赋值
[root@rocky9-15 ~]# file=/var/log/nginx/access.log
[root@rocky9-15 ~]# filename=${file##*/} #匹配到access.log
[root@rocky9-15 ~]# echo $filename
access.log
[root@rocky9-15 ~]# filedir=${file%/*} #匹配到/var/log/nginx
[root@rocky9-15 ~]# echo $filedir
/var/log/nginx
字符串替换
[root@rocky9-15 ~]# str="apple, tree, apple tree, apple"
[root@rocky9-15 ~]# echo ${str/apple/APPLE} #将字符串的第一个apple替换成为APPLE
APPLE, tree, apple tree, apple
[root@rocky9-15 ~]# echo ${str//apple/APPLE} #将字符串的所有apple替换成为APPLE
APPLE, tree, APPLE tree, APPLE
7.4 、高级变量
-
默认值处理:
${var:-default}(变量为空时使用默认值) -
错误检查:
${var:?error_msg}(变量未定义时报错退出) -
条件赋值:
${var:=value}(为空时赋值并返回)[root@rocky9-15 ~]# unset name [root@rocky9-15 ~]# echo ${name:-"test"} #变量为空时返回默认值(不修改变量) test [root@rocky9-15 ~]# echo $name [root@rocky9-15 ~]# echo ${count:=10} #变量为空时赋值并返回默认值 10 [root@rocky9-15 ~]# echo $count 10 [root@rocky9-15 ~]# echo ${path:?"路径未定义"} #变量为空时报错退出 -bash: path: 路径未定义 [root@rocky9-15 ~]# echo ${title:+"高级教程"} #变量非空时替换值 高级教程
8. 求10个随机数的最大值与最小值。
#!/bin/bash
random_numbers=() #创建空数组存储数据
# 生成10个随机数并存入数组
for i in {1..10}; do
random_numbers[i-1]=$((RANDOM % 100))
done
max_num=${random_numbers[0]} # 初始化为第一个元素
min_num=${random_numbers[0]} # 初始化为第一个元素
for i in {1..10}; do #通过循环遍历查找出最大值和最小
if [ ${random_numbers[i-1]} -gt $max_num ]; then
max_num=${random_numbers[i-1]}
fi
if [ ${random_numbers[i-1]} -lt $min_num ]; then
min_num=${random_numbers[i-1]}
fi
done
echo "最大值: $max_num"
echo "最小值: $min_num"
9. 使用递归调用,完成阶乘算法实现。
#!/bin/bash
# 定义阶乘函数
factorial() {
# 参数检查:如果输入小于等于1,直接返回1(0!和1!都等于1)
if [ $1 -le 1 ]; then
echo 1
else
# 递归调用:计算(n-1)的阶乘
last=$(factorial $(( $1 - 1 )))
# 返回结果:n * (n-1)!
echo $(( $1 * last ))
fi
}
# 用户交互部分
read -p "请输入一个正整数: " num # 提示用户输入
result=$(factorial $num) # 调用阶乘函数
echo "$num 的阶乘是: $result" # 输出计算结果
[root@rocky9-15 week4]# bash jiecheng.sh
请输入一个正整数: 6
6 的阶乘是: 720
10. 解析进程和线程的区别? 解析进程的结构。
10.1、进程和线程区别
1. 定义与基本特性
| 进程 | 线程 |
|---|---|
| 进程是程序的一次执行实例,拥有独立的内存空间和系统资源(如文件句柄、网络连接等)。 | 线程是进程内的一个执行单元,共享进程的内存和资源,但拥有独立的栈空间和程序计数器。 |
| 独立性强:一个进程崩溃不会直接影响其他进程。 | 依赖性强:一个线程崩溃可能导致整个进程终止。 |
2. 资源分配
| 进程 | 线程 |
|---|---|
| 独立内存空间:每个进程拥有独立的虚拟地址空间(代码段、数据段、堆、栈等)。 | 共享内存:线程共享进程的堆和全局变量,仅各自保留独立的栈。 |
| 资源开销大:进程创建、切换和销毁需要分配或回收内存、文件描述符等资源,成本较高。 | 轻量级:线程的创建、切换和销毁成本低,因为它们共享进程资源。 |
3. 执行与切换
| 进程 | 线程 |
|---|---|
| 进程间切换:需要保存和恢复整个进程的上下文(如内存映射、寄存器状态等),开销大。 | 线程间切换:仅需保存线程的栈和寄存器状态,开销小。 |
| 进程是操作系统调度资源的基本单位。 | 线程是操作系统调度的最小执行单位。 |
4. 通信机制
| 进程 | 线程 |
|---|---|
| 进程间通信(IPC):必须通过管道(Pipe)、消息队列(Message Queue)、共享内存(Shared Memory)、信号(Signal)、套接字(Socket)等机制。 | 线程间通信:直接读写共享内存即可(需通过锁、信号量等机制同步)。 |
| 安全性高:进程间隔离性好,但通信复杂。 | 效率高:线程共享内存,通信简单,但容易导致竞态条件(Race Condition)等同步问题。 |
5. 应用场景
| 进程 | 线程 |
|---|---|
| 高隔离性和稳定性:例如浏览器每个标签页作为独立进程(崩溃不影响其他标签页)。 | 高并发和性能:例如 Web 服务器(如 Nginx)通过多线程处理大量并发请求。 |
| 分布式系统:不同进程可运行在不同机器上。 | 计算密集型任务:利用多核 CPU 并行运算(如科学计算、图像处理)。 |
6. 典型比喻
- 进程:类似一家公司,每个公司有独立的资金、员工、办公室资源,公司之间需要通过合同或邮件沟通。
- 线程:类似公司内的部门,共享公司资源(资金、办公室),部门间协作效率高,但需要小心资源冲突(如会议室争抢)。
10.2、进程的结构
进程的结构主要由三个核心部分组成:
1. 程序段(代码段)
- 定义:存储进程需要执行的机器指令代码,通常是只读的,防止意外修改。
- 示例:如一个运行中的浏览器进程包含渲染引擎、网络请求处理等功能的代码。
2. 数据段
组成:
-
静态数据区:存放全局变量、静态变量等初始化数据。
-
堆(Heap):动态分配内存区域,用于
malloc或new操作的内存管理。 -
栈(Stack):存储函数调用时的局部变量、返回地址等信息,每个线程通常有独立栈。
作用:为进程运行时提供必要的数据存储支持。
3. 进程控制块(PCB)
- 定义:操作系统为每个进程创建的核心数据结构,记录进程的管理和调度信息。
- 关键内容:
- 标识信息:进程ID(PID)、父进程ID等。
- 状态信息:运行态、就绪态、阻塞态等状态标记。
- 控制信息:程序计数器(指向下一条指令地址)、CPU寄存器值、内存分配表等。
- 资源信息:打开的文件列表、I/O设备占用情况。
- 重要性:PCB是操作系统感知和管理进程的唯一标识,进程创建时分配,终止时回收。
结构关系示意图
进程
├── 程序段(代码)
├── 数据段
│ ├── 静态数据区
│ ├── 堆(动态内存)
│ └── 栈(函数调用)
└── PCB
├── 进程状态
├── 寄存器值
└── 资源指针...
11. 结合进程管理命令,说明进程各种状态。
进程有五个状态:
创建状态、就绪状态 、执行状态 、阻塞状态 、终止状态

下面是使用命令的具体查看
1、创建状态(New)
当用户执行fork()或exec()系统调用时,内核会为新进程分配PCB结构体并初始化。此时进程处于创建态,在ps命令中不可见(内核态操作)。创建完成后立即转入就绪态。
2. 就绪状态(Ready)
通过ps -l可查看就绪态进程:
[root@rocky9-15 ~]# ps -l
F S UID PID PPID C PRI NI ADDR SZ WCHAN TTY TIME CMD
4 S 0 5197 5196 0 80 0 - 56052 do_wai pts/2 00:00:00 bash
4 R 0 5450 5197 0 80 0 - 56368 - pts/2 00:00:00 ps
其中S列为R表示就绪态,WCHAN为空说明未阻塞。
3. 执行状态(Running)
使用top命令实时观察

S列显示R且%CPU>0即为运行态。
4. 阻塞状态(Blocked)
两种阻塞类型:
- 可中断睡眠(S):
ps -l中S列为S - 不可中断睡眠(D):常见于磁盘IO,
ps -l中S列为D
5. 终止状态(Terminated)
僵尸进程查看:
[root@rocky9-15 ~]# ps -ef | grep 'defunct'
root 5472 5197 0 23:46 pts/2 00:00:00 grep --color=auto defunct
显示<defunct>标记的即为僵尸进程。
12. 说明IPC通信和RPC通信实现的方式。
一、IPC(进程间通信)的实现方式
1、共享内存
- 多个进程共享同一块物理内存区域,实现高效数据交换。需通过信号量或互斥锁解决并发访问问题
2、管道(Pipe)与命名管道(FIFO
- 匿名管道:单向通信,仅适用于父子进程或兄弟进程间的数据传输,基于文件描述符操作
- 命名管道:通过文件系统路径标识,支持无亲缘关系进程间的通信,采用先进先出队列机制
3、消息队列
- 以结构化消息为单位传递数据,支持异步通信。消息队列通过内核维护的链表结构管理消息,允许进程按优先级读
4、信号量(Semaphore)
- 用于进程间同步,通过原子操作控制共享资源的访问。例如,防止共享内存的读写冲突
5、套接字(Socket)
- 支持本地(如Unix Domain Socket)或网络通信。本地套接字通过文件路径标识,无需网络协议栈,传输效率高于传统IPC机制
二、RPC(远程过程调用)的实现方式
1、客户端与服务端存根(Stub)
- 客户端存根:将本地方法调用参数序列化后封装为网络传输格式,发送至服务端
- 服务端存根:接收请求并反序列化参数,调用目标方法后返回结果
2、序列化与反序列化 - 使用Protocol Buffers、JSON等协议将参数和返回值转换为字节流,确保跨语言和跨平台兼容性
3、网络传输协议
- 基于TCP/IP或HTTP协议实现跨进程通信
- 例如,gRPC采用HTTP/2协议优化性能,支持双向流式传输
4、服务注册与发现
- 通过注册中心(如ZooKeeper、Consul)管理服务地址,客户端动态获取服务端代理(Proxy),实现负载均衡与故障转移
5、跨设备通信实现
- 在分布式系统中,RPC依赖软总线驱动处理跨设备调用,通过统一协议实现设备间协同
三、总结
| 特性 | IPC | RPC |
|---|---|---|
| 通信范围 | 本地进程间(单设备内) | 跨设备或远程进程间 |
| 依赖机制 | 操作系统内核(如信号量、共享内存) | 网络协议栈及序列化框架 |
| 性能 | 高(直接内存访问) | 较低(涉及网络传输开销) |
| 典型场景 | 本地服务协同(如数据库读写) | 微服务、分布式系统调用 |
13. 总结Linux,前台和后台作业的区别,并说明如何在前台和后台中进行状态转换。
13.1、Linux,前台和后台作业的区别
一、终端交互性
- 前台作业:
独占终端控制权,运行时阻塞用户输入,实时显示输出到当前终端。
可通过 Ctrl+C 终止,或 Ctrl+Z 暂停并转为后台运行。 - 后台作业:
启动后立即释放终端(需在命令末尾添加 &),用户可继续操作其他任务。
默认输出仍显示到终端,可能干扰用户操作(建议重定向到文件)。
二、生命周期与控制
-
依赖关系:
前台作业的父进程为当前 Shell,关闭终端或会话会直接终止前台进程。
后台作业默认依赖当前 Shell,终端退出时可能被终止(可通过 nohup 或 disown 脱离会话)。 -
状态管理:
使用 jobs 查看后台作业列表(包含作业编号及状态)。
fg %n 将编号为 n 的后台作业调至前台,bg %n 恢复暂停的后台作业运行。
三、典型场景与操作
-
前台适用场景:
需要交互的程序(如 vim、top),或需实时监控输出的任务。 -
后台适用场景:
耗时任务(如编译、数据处理)或长期运行的服务(配合 nohup command & 实现守护进程)。
四、核心差异对比图
| 对比维度 | 前台作业 | 后台作业 |
|---|---|---|
| 终端交互性 | 独占输入输出,实时交互 | 释放终端,用户可并行操作 |
| 生命周期 | 终端关闭则终止 | 可脱离终端长期运行 |
| 启动方式 | 直接输入命令(默认) | 命令末尾添加 & |
| 管理命令 | Ctrl+C/Z、kill PID | jobs、fg、bg、nohup |
13.2、前台和后台中进行状态转换
[root@rocky9-15 ~]# sleep 60 & #加&号将前台作业变成后台作业
[2] 6307
[1] 已完成 sleep 60
[root@rocky9-15 ~]# sleep 100 #前台作业暂停并转后台
^Z
[1]+ 已停止 sleep 100 #按ctrl+Z
[root@rocky9-15 ~]# bg %1 #恢复作业并转为后台运行
[1]+ sleep 100 &
[root@rocky9-15 ~]# fg %1 # 将作业号 1 的后台作业切换到前台(恢复交互控制)
[root@rocky9-15 ~]# sleep 1000 &
[1] 6313
[root@rocky9-15 ~]# jobs -l # 显示所有作业及详细信息(作业号、PID、状态)
[1]+ 6313 运行中 sleep 1000 &
14. 实现定时任务,每日凌晨1点,删除指定文件(自己创建即可)
crontab时间字段定义
* * * * *
┬ ┬ ┬ ┬ ┬
│ │ │ │ └─ 星期(0-7,0和7均为周日)
│ │ │ └─── 月份(1-12或英文缩写)
│ │ └───── 日期(1-31)
│ └─────── 小时(0-23)
└───────── 分钟(0-59)
[root@rocky9-15 ~]# crontab -l
0 1 * * * rm -rf /test/1.txt
15. 实现定时任务每月月初对指定文件进行压缩(自己创建文件)
0 0 1 * * tar -czvf archive.tar.gz /homework/
16. 通过shell编程完成,30鸡和兔的头,80鸡和兔的脚,分别有几只鸡,几只兔?
#!/bin/bash
x=30 #动物总头数
y=80 #动物总脚数
for ((i=1; i<=x; i++))
do
t1=$i #鸡头的数量
t2=$((x-i)) #兔头的数量
j1=$((t1*2)) #鸡脚的数量
j2=$((t2*4)) #兔脚的数量
if [ $((j1 + j2)) -eq $y ]; then # 注意then前加空格
echo "笼子里一共有:$t1只鸡"
echo "笼子里一共有:$t2只兔"
exit 0
fi
done
echo "错误:没有找到符合条件的组合"
exit 1
[root@rocky9-15 week4]# bash rabbit.sh
笼子里一共有:20只鸡
笼子里一共有:10只兔
17. 结合编程的for循环,条件测试,条件组合,完成批量创建100个用户,
1)for遍历1..100
2)先id判断是否存在
3)用户存在则说明存在,用户不存在则添加用户并说明已添加。
#!/bin/bash
for i in {1..100}
do
user="user$i" #创建新用户的用户名
# 进行用户是否存在的判断
if id -u "$user" >/dev/null 2>&1; then
echo "$user已经存在,无法创建"
else
useradd $user
echo "$user不存在,已经成功创建该用户"
fi
done

18. 练习题:练习top,htop, iotop,iostat等课程相关工具的使用
18.1、top
定义
top 是 Linux 中最常用的 实时系统监视工具,用于动态查看进程活动和系统资源使用情况(类似 Windows 的任务管理器)。
一、核心功能
| 功能 | 说明 |
|---|---|
| 进程监控 | 实时显示所有进程的 CPU、内存、优先级等关键指标 |
| 资源统计 | 汇总全局 CPU、内存、交换分区、负载平均值等系统级数据 |
| 交互操作 | 支持动态排序、终止进程、调整刷新频率等操作 |
| 性能诊断 | 快速识别高 CPU/内存占用的进程,定位系统瓶颈 |
二、界面解析(按下 z 可高亮颜色)
执行 top 后界面分为两部分:
1. 系统概览区(头部)
[root@rocky9-15 ~]# top
top - 21:28:21 up 23:12, 3 users, load average: 0.01, 0.04, 0.12
Tasks: 319 total, 1 running, 318 sleeping, 0 stopped, 0 zombie
%Cpu(s): 1.0 us, 0.3 sy, 0.0 ni, 98.5 id, 0.0 wa, 0.2 hi, 0.0 si, 0.0 st
MiB Mem : 3627.6 total, 1934.3 free, 1371.9 used, 577.7 buff/cache
MiB Swap: 4012.0 total, 4008.0 free, 4.0 used. 2255.8 avail Mem
- 负载平均值(load average):1分钟/5分钟/15分钟的平均负载(建议 ≤ CPU核心数)¹
- CPU 使用率:用户态(
us)、内核态(sy)、空闲(id)、I/O 等待(wa)等占比 - 内存/交换分区:总量(
total)、空闲(free)、已用(used)、缓存(buff/cache)
2. 进程列表区(主体)

- PID:进程 ID
- %CPU:进程 CPU 使用率(多核下可能超过 100%)
- %MEM:进程物理内存占用百分比
- VIRT/RES/SHR:虚拟内存/物理内存/共享内存(单位 KiB)
- S:进程状态(
R=运行,S=睡眠,D=不可中断睡眠,Z=僵尸进程)
三、常用交互命令
在 top 界面中按以下快捷键操作:
| 快捷键 | 功能 | 示例 |
|---|---|---|
P |
按 CPU 使用率排序(默认) | 快速定位 CPU 密集型进程 |
M |
按内存使用率排序 | 找出内存泄漏进程 |
k |
终止进程(需输入 PID) | kill 命令的快捷方式 |
r |
调整进程优先级(nice 值) |
降低高负载进程的优先级 |
1 |
展开显示所有 CPU 核心的单独使用率 | 检查多核负载均衡 |
d |
修改刷新间隔(默认 3 秒) | 输入 2 改为 2 秒刷新 |
z |
切换颜色高亮 | 增强可读性 |
q |
退出 top |
18.2、htop
定义:
htop 是 Linux 和类 Unix 系统中广泛使用的 交互式系统监控工具,可视为传统 top 命令的增强版,提供更友好的界面和更强大的功能
一、核心特点
- 交互式彩色界面
支持鼠标操作,以彩色图表和动态布局直观展示 CPU、内存、交换分区等资源使用情况。 - 实时监控与动态更新
可自定义刷新频率(默认 1-2 秒),实时跟踪系统资源和进程活动。 - 进程管理功能
支持直接终止进程、调整优先级(nice值)、查看进程树状结构等
二、主要功能
| 功能 | 说明 |
|---|---|
| 资源可视化 | 顶部显示 CPU、内存、交换分区的使用率图形(条形图或数值) |
| 进程排序 | 支持按 CPU、内存、运行时间等多列排序(快捷键 F6) |
| 搜索与过滤 | 可按进程名、用户或 PID 快速定位目标进程 |
| 进程树状视图 | 展示进程间的父子关系(快捷键 t) |
| 批量操作 | 可标记多个进程并统一终止或调整优先级7 |
使用界面

18.3、 iotop
一、iotop 简介
iotop 是一款实时监控磁盘 I/O 使用情况的工具,可显示进程/线程级别的读写带宽、I/O 优先级等信息,支持交互式操作和批量模式。适合排查高 I/O 负载进程。
二、基本用法
1. 交互模式
直接运行 iotop 进入实时监控界面,默认按 I/O 使用量降序排列。
输出字段说明:
- Total DISK READ/WRITE:总读写带宽
- Actual DISK READ/WRITE:实际磁盘 I/O 带宽
- TID:线程 ID
- PRIO:I/O 优先级(由
ionice设置) - DISK READ/DISK WRITE:进程读写速率
2. 常用选项
| 选项 | 描述 |
|---|---|
-o |
仅显示有 I/O 活动的进程 |
-b |
批量模式(非交互,适用于日志记录) |
-d N |
设置刷新间隔为 N 秒(默认 1 秒) |
-p PID |
监控指定进程的 I/O |
-u USER |
监控指定用户的进程 |
三、交互快捷键
| 快捷键 | 功能 |
|---|---|
| ←/→ | 切换排序字段(默认按 I/O 排序) |
| r | 反转排序顺序 |
| o | 切换“仅显示活跃 I/O 进程”模式 |
| a | 显示累积 I/O 总量 |
| p | 切换进程/线程显示模式 |
| q | 退出程序 |
使用界面

18.4、iostat
一、iostat 定义
iostat (Input/Output Statistics) 是 Linux/Unix 系统中用于监控 磁盘 I/O 性能 和 CPU 使用率 的核心工具,属于 sysstat 软件包的组成部分。它通过统计设备活动时间和系统配置数据,帮助用户快速定位存储瓶颈或 CPU 负载问题。
二、功能概述
- 磁盘 I/O 监控
- 提供 读写吞吐量(MB/s)、IOPS(I/O 操作次数/秒)、队列深度 等关键指标
- 支持分析单个磁盘/分区的性能瓶颈(如高延迟或队列拥塞)
- 显示内核的 I/O 合并优化效果(如
rrqm/s和wrqm/s)
- CPU 使用率监控
- 统计 用户态(%user)、系统态(%system)、空闲(%idle) 及 I/O 等待(%iowait) 的 CPU 时间占比
- 若
%iowait持续高于 5%,通常表明存储设备成为系统瓶颈
- 数据分析模式
- 支持动态刷新数据(如每秒一次),适用于实时监控
- 可结合
sar工具生成长期性能趋势报告
三、工具特点
- 广泛适用性:默认集成于主流 Linux 发行版,需通过安装
sysstat包激活 - 轻量级交互:命令简洁,支持参数灵活调整输出(如
-x显示扩展状态、-d仅显示设备利用率) - 全局视角:侧重系统整体性能分析,不支持进程级深度监控(需结合
iotop等工具)
四、典型应用场景
- 存储性能瓶颈排查:识别高延迟磁盘或异常 I/O 负载
- CPU 负载分析:检测由 I/O 等待导致的 CPU 资源浪费
- 系统调优参考:通过历史数据优化存储配置(如 RAID 策略、文件系统选择)
使用界面

19. 练习课程中awk的使用
19.1、AWK 核心概念
AWK 是逐行处理文本的编程工具,基本结构为:
awk 'BEGIN {预处理} 模式 {动作} END {后处理}' 文件
19.2、字段处理基础
- 默认以空格/制表符分隔列,用
$1、$2...访问列:
awk '{print "第一列:", $1, "最后一列:", $NF}' file.txt
root@ubuntu24-13:~# awk -F ":" '{print "第一列:",$1,"最后一列:",$NF}' /etc/passwd #输出passwd的第一列和最后一列
第一列: root 最后一列: /bin/bash
第一列: daemon 最后一列: /usr/sbin/nologin
第一列: bin 最后一列: /usr/sbin/nologin
第一列: sys 最后一列: /usr/sbin/nologin
第一列: sync 最后一列: /bin/sync
第一列: games 最后一列: /usr/sbin/nologin
第一列: man 最后一列: /usr/sbin/nologin
第一列: lp 最后一列: /usr/sbin/nologin
第一列: mail 最后一列: /usr/sbin/nologin
第一列: news 最后一列: /usr/sbin/nologin
第一列: uucp 最后一列: /usr/sbin/nologin
第一列: proxy 最后一列: /usr/sbin/nologin
第一列: www-data 最后一列: /usr/sbin/nologin
第一列: backup 最后一列: /usr/sbin/nologin
19.3、条件判断全解析

示例:
[root@rocky9-15 week4]# cat employee.txt #创建一个内容文档
ID Name Age Dept Salary
101 Alice 28 Sales 5000
102 Bob 35 IT 6500
103 Carol 22 HR 4800
104 David 40 IT 7000
105 Eve 31 Sales 5500
[root@rocky9-15 week4]# awk '$4 == "IT" {print $2, $5}' employee.txt #条件为真,输出内容
Bob 6500
David 7000
[root@rocky9-15 week4]# awk '$4 == "IT_test" {print $2, $5}' employee.txt #条件为假,不输出内容
[root@rocky9-15 week4]# awk '"" {print $2, $5}' employee.txt #条件为空,不执行
[root@rocky9-15 week4]# awk '" " {print $2, $5}' employee.txt #条件非空,执行
Name Salary
Alice 5000
Bob 6500
Carol 4800
David 7000
Eve 5500
[root@rocky9-15 week4]# awk -v n=0 'n++' employee.txt #第一行的值为0不打印,其余的值都打印
101 Alice 28 Sales 5000
102 Bob 35 IT 6500
103 Carol 22 HR 4800
104 David 40 IT 7000
105 Eve 31 Sales 5500
[root@rocky9-15 week4]# awk -v n=0 '!n++' employee.txt #第一行的值把为0打印,其余的值都不打印
ID Name Age Dept Salary
[root@rocky9-15 week4]# awk '$2 ~/a/ {print $0}' employee.txt #打印文件第二列数值包含a的值
ID Name Age Dept Salary
103 Carol 22 HR 4800
104 David 40 IT 7000
[root@rocky9-15 week4]# awk '$2 !~/a/ {print $0}' employee.txt #打印文件第二列数值把包含a的值
101 Alice 28 Sales 5000
102 Bob 35 IT 6500
105 Eve 31 Sales 5500
[root@rocky9-15 week4]# awk 'BEGIN {sum=0} $4 == "IT" {sum += $5} END {print "IT总工资:",sum}' employee.txt #计算it部门总工资
IT总工资: 13500
[root@rocky9-15 week4]# awk 'NR>1 && $4 != "" {dept[$4] += $5} END {for (d in dept) print d ":", dept[d]}' employee.txt #输个各个部门的工资
IT: 13500
Sales: 10500
HR: 4800

浙公网安备 33010602011771号