介绍
FRAME Studio 正在检查用于活动照片导出的 Linux 工作机。在监测较长的工作过程之前,需要可信的读数:CPU 非空闲时间、不能随时供新程序使用的内存比例,以及导出目录所在文件系统的使用率。较高的读数是需要理解的信号,不能证明照片处理失败。
你将实现三个简短的 Bash 函数,并使用运行真实 Linux 命令的现成适配程序。前置知识包括终端路径,以及 Shell for Beginners 中的 Bash 变量、函数、条件和循环。准备好的 shell 程序负责命令衔接;你会阅读这些衔接代码,并实现百分比逻辑。这是独立的 Linux 实例,含两个小型、真实的 ext4 教学文件系统。创建和挂载由环境准备完成,不是学员任务。时长为作者估计,包含阅读和普通错误处理。
测量 CPU 非空闲时间
本步骤先观察一个可用的资源快照,再实现 CPU 数值转换。
从 Terminal 开始。本实验的所有命令都在这里执行。进入准备好的工作目录;pwd 显示当前位置,ls 列出文件。如果之后找不到相对路径的文件,请重新执行完整的 cd 命令,不要重置实例。
如何输入命令
输入前先点击 Terminal 内部。只复制命令块中的内容,不要输入命令提示符、外侧的反引号或预期输出示例。每条命令输入后按 Enter,等待提示符重新出现再继续。命令执行成功时也可能没有任何输出。整个实验请保持使用同一个 Terminal。
cd /home/labex/project/resource-watch
pwd
路径应以 /resource-watch 结尾。使用 Bash 运行准备好的演示:
bash demo.sh
第一行给出四个字段名称。下一行包含 UTC 时间戳和三个真实百分比,数值会变化。demo.sh 是提供的正常样例,不会替你完成函数或保存答案。
UTC timestamp | CPU non-idle % | memory pressure % | target filesystem used %
2026-...Z ... ... ...
CPU 百分比描述实例各虚拟 CPU 的时间分配。vmstat 报告系统活动。在 vmstat 1 2 中,1 是以秒为单位的间隔,2 是报告次数。第一份 CPU 报告是开机以来的平均值,第二份覆盖新的采样区间。先运行,再提取字段:
LC_ALL=C vmstat 1 2
LC_ALL=C 为这条命令设置英文和稳定的数值格式。在 CPU 列中找到 id,它表示空闲时间。本课程定义非空闲 = 100 - 空闲。非空闲包含 I/O 等待和被宿主抢占的时间,不只是执行你的程序的时间,也不是故障诊断。
适配程序使用管道:| 把一条命令的输出传给下一条。tail -n 1 选择最后一行。awk '{print $15}' 打印按空白分隔的第十五个字段,在预备环境的 procps 版本中对应 id 列。单引号把 $15 保留给 awk,而不是由 shell 展开。确认提取结果是整数:
LC_ALL=C vmstat 1 2 | tail -n 1 | awk '{print $15}'
接下来编辑提供的函数。nano 是终端编辑器。打开指定文件,只替换其中的 :(位于 cpu_nonidle 内),其余两个函数保持不变。冒号是无操作的占位符。
nano metrics.sh
用方向键移动光标。在第一个函数中,只删除冒号所在行,输入下方展示的两行缩进代码。保留函数名、左右花括号及其他函数。完整函数示例展示的是修改后的目标,不要在原函数下方再粘贴一份。缩进方便阅读,花括号和拼写则必须正确。
使第一个函数如下所示:
cpu_nonidle() {
local idle=$1
echo $((100 - idle))
}
$1 是函数的第一个参数。local 让变量只在此函数内有效。$((...)) 执行整数运算,echo 打印结果。按 Ctrl+O、Enter、Ctrl+X 保存并退出 nano。如果之后的编辑引发语法错误,重新打开此文件,修正相关函数;现成采样程序保持不变。

图中只完成了第一个函数,另外两处冒号占位符是有意保留的。nano 底部的尖号表示 Ctrl 键,例如 ^O 是按住 Ctrl 再按 O,不是输入这两个字符。

按 Ctrl+O 后,nano 在底部询问保存文件名。保持已有名称,按 Enter 确认,再按 Ctrl+X 返回 shell 提示符。如果打开了错误的文件,按 Ctrl+X,在询问是否保存时选择 N,然后打开正确文件。编辑器尚未退出时不要输入 shell 命令。
source 将函数定义加载到当前 shell。Terminal 启动的是 Zsh,而本练习使用 Bash,因此用 bash -c 在 Bash 中执行引号内的测试。外层单引号为 Bash 保留内部函数命令。
bash -c 'source ./metrics.sh; cpu_nonidle 97'
3
这里给定的空闲值用于测试运算,不代表当前 CPU 的非空闲时间恰好为 3%。再检查两个端点:
bash -c 'source ./metrics.sh; cpu_nonidle 0; cpu_nonidle 100'
100
0
此函数可处理 0 到 100 的任意整数空闲值。真实采样程序将传入新测得的数值。
区分可用内存与完全空闲内存
本步骤利用 Linux 估计可供新应用使用的内存来计算内存压力。
保持在 Terminal,目录为 /home/labex/project/resource-watch。free -k 以 KiB(每单位 1024 字节)显示内存。先执行命令,再解析输出:
LC_ALL=C free -k
阅读 Mem: 行。free 表示完全未使用的内存;available 估计无需交换即可供新应用使用的内存,其中包括部分可回收缓存。不要把所有缓存都当成永久不可用。本课程采用 floor((total - available) * 100 / total) 作为内存压力百分比。它不能预测未来某次具体内存分配一定成功。
适配程序从同一行选择总量和可用量。在 awk 中,/^Mem:/ 匹配以 Mem: 开头的行;$2 和 $7 分别选择第二、第七个字段。
LC_ALL=C free -k | awk '/^Mem:/ {print $2, $7}'
输出先是总量,再是可用内存。两者单位相同,因此可以计算比例。例如,总量 1000、可用量 750 对应 25%,不是 75%。
打开文件,只替换 memory_pressure 的占位实现:
nano metrics.sh
memory_pressure() {
local total=$1 available=$2
echo $(((total - available) * 100 / total))
}
Bash 整数除法截去小数部分。这里输入均非负且总量为正,因此截断等同于向下取整。先乘再除,避免过早丢失小数部分。按 Ctrl+O、Enter、Ctrl+X 保存。
bash -c 'source ./metrics.sh; memory_pressure 1000 750; memory_pressure 3 2'
25
33
三个单位中一个不可用时,33 是有意的结果。函数契约要求使用相同大小的整数单位,可用量在零与总量之间。无效输入解析由本小练习之外的程序处理。
第一个测试中,不可用量是 1000 - 750 = 250,所以 250 × 100 ÷ 1000 = 25。第二个测试中,三份里有一份不可用,33.333… 因函数返回整数而变成 33。函数的第二个参数是可用内存量,不是已经计算好的百分比。保留上一步完成的 CPU 函数。
对正确的文件系统进行采样
本步骤完成文件系统函数,并保存一次完整观测。
保持在 Terminal,目录为 /home/labex/project/resource-watch。exports 和 reference 目录分别位于准备好的不同 ext4 文件系统上。两处的原始素材和备注都必须保留。你只观察空间,不要删除素材、修改挂载或尝试填满文件系统。
df 报告给定路径所在的文件系统。-P 使用可预测的每文件系统一行布局。比较两个路径:
df -P exports reference
阅读 Capacity,而不是目录里的文件数量。exports 的使用率应低于 reference。运行 df / 观察的是另一个文件系统,不能替代选定目标。
在 nano 中只替换 filesystem_used:
nano metrics.sh
filesystem_used() {
df -P "$1" | awk 'NR == 2 {gsub(/%/, "", $5); print $5}'
}
双引号让传入路径保持为一个参数。NR == 2 选择表头之后的数据行。gsub 在打印第五个字段前去掉 %。按 Ctrl+O、Enter、Ctrl+X 保存。只要能返回请求文件系统的同一整数,也允许其他实现。
bash -c 'source ./metrics.sh; filesystem_used exports; filesystem_used reference'
两个数应分别与对应的 df 行一致。最后运行提供的驱动程序:
bash snapshot.sh
现在它会输出 UTC 时间戳、CPU 非空闲、内存压力、目标文件系统使用率,以制表符分隔。CPU 和内存在命令之间可能变化。如果希望把各项观测连接起来,可以阅读适配程序:
cat capture.sh
适配程序运行 vmstat 和 free,调用你的函数,并用 df 读取目标。$(...) 捕获命令输出;read -r 把按空白分隔的字段赋给变量,<<< 把捕获的字符串提供给 read。这些衔接细节已经准备好,三个百分比由你的函数决定。
保存一次真实快照。> 重定向输出并替换这一个快照文件,不会改变原操作员历史。
扩展名 .tsv 表示制表符分隔值:每行一条观测,字段之间用制表符分隔。保存的快照依次有四个字段:UTC 时间戳、CPU 非空闲百分比、内存压力百分比、目标文件系统使用百分比。UTC 是统一的时间标准,时间戳末尾的 Z 表示 UTC。这些百分比描述不同资源,不要相加,也不必合计为 100。
bash snapshot.sh > snapshot.tsv
cat snapshot.tsv
如果路径或函数名拼错,请使用 ls,重新打开 metrics.sh 修正,然后再次执行快照命令。不要用编造的数字替代失败的观测。你现在拥有计算方式与观测目标都明确的 Bash 采样工具。
总结
你在新的时间区间测量了 CPU 非空闲时间,用可用内存计算压力,并选择了实际目标所在的文件系统。三个 Bash 函数现在能生成真实资源快照。下一个独立实验会提供这些函数,并加入告警规则和保留历史。



