第12天Linux自学:用Shell脚本打造系统健康巡检工具

发布时间:2026/10/18 5:49:35
第12天Linux自学:用Shell脚本打造系统健康巡检工具 今天是我自学 Linux 的第 12 天。和前几天最大的不同在于我不再满足于“会用某条命令”而是开始用 Shell 把零散命令串成能干的脚本。前 11 天里我完成了虚拟机搭建、基础命令、文件权限、文本处理、管道重定向、用户和用户组管理这些板块能查目录、能改权限、能看日志、能找大文件可每次要统计一批文件大小或者巡检一台服务器的磁盘和内存我还得一条一条手敲命令。第 12 天这个节点特别适合把前面的知识“焊”在一起。这篇不仅是我今天的复盘也适合同样在自学 Linux 10 到 15 天的人参考我会把变量、条件判断、循环、写脚本的完整流程以及今天踩过的几个真正让人抓狂的坑一次性讲清楚。1. 第 12 天的学习主线从“记住命令”转向“写出脚本”1.1 为什么恰好是第 12 天进入 Shell 脚本很多自学路线喜欢把脚本放在两个月以后我觉得这是误解。第 12 天进入脚本不是因为我基础已经好到不行恰恰相反我前几天的命令还不算熟。正因为不熟才更需要用脚本去强迫自己“组织命令”而不是“背诵命令”。具体来说我会用grep、awk、df、free、uptime这些命令去采集信息但每次都手动输入效率很低。而脚本能把这些操作固化下来检查磁盘、看内存、看 CPU 负载这些高频操作一旦写成脚本以后每次运行只需要执行一个文件名。脚本其实是学习 Linux 过程中“从记忆到自动化”的转折点也是我判断自己能不能真正用 Linux 干活的分水岭。提示如果你正处于自学第 8 到第 10 天可以提前看一眼脚本不需要精通只要理解“脚本就是命令的顺序执行 逻辑判断”后面的路会顺很多。1.2 今天的目标和一个可以抄的练习计划我给自己定的目标是写一个只要双击就能完成的系统健康巡检脚本至少能输出磁盘使用率、内存剩余量、CPU 负载以及某个关键服务是否在运行。这不是多高级的功能但它能把我前 11 天学到的所有核心命令全部用上df、free、loadavg文件读取、systemctl状态检查、变量、条件判断、echo输出甚至还有定时任务。为了实现这个目标我给自己安排了一个三段的练习计划你可以直接参考上午 90 分钟系统过一遍变量、if条件判断、for循环。重点不是背语法而是在终端里把每个例子敲一遍看输出。下午 120 分钟完整实现巡检脚本把脚本从“能跑”改到“好用”。晚上 40 分钟复盘今天踩的坑整理成笔记顺便规划第 13 天的定时任务。这套计划的底层逻辑很简单上午输入语法下午输出作品晚上清理漏洞。如果不做作品只看语法第 12 天结束你会发现自己什么也没留下。2. 脚本入门的核心语法与我的理解2.1 变量赋值第一个让我踩坑的地方Shell 变量是我今天最早接触的内容也是我最早翻车的地方。第一次我写name test结果终端直接报错command not found。原因很简单Shell 的变量赋值语法里等号两边是不能有空格的空格会把name当成命令把 test当成参数。正确写法是nametest echo $name这里我建议你把$name理解为“取这个变量的值”就像去储物柜里把东西取出来。越早接受这种符号逻辑后面写脚本越顺。还要留意变量最好不要用大小写混合、也不要用$开头或者包含连字符我见过有人定义一个叫my-name的变量结果脚本直接报语法错就是因为连字符被解释成了减号。另一个常见的坑是引用变量时要不要加双引号。比如path/home/listen/my files ls $path如果路径里有空格ls会把这个变量拆成两个参数从而找不到目录。正确写法是ls $path这个细节我不止一次忽略直到今天才发现“不加引号”造成的报错比想象中多得多。2.2 条件判断if、test 和 [ ] 的真实关系编写脚本基本都会用到条件判断而我一开始完全被if [ -d $dir ]这种写法搞晕了。后来我把它们拆开看就通了if是一个语法关键字。[ ]其实就是test命令的别名。[ -d $dir ]的意思是测试变量$dir所指向的路径是不是一个目录。换句话说[ ]左侧和右侧必须有空格否则 Shell 会把[当成一个普通字符而不是一个命令。这个空格问题如果不亲身踩一回真的很难意识到。我写的第一个判断就写成[$dir]报错[: missing ]检查了半天才反应过来。我还建议你第 12 天就把数字比较和字符串比较分开记忆。数字用-eq、-ne、-gt、-lt字符串用和!。比如count5 if [ $count -gt 3 ]; then echo 数量大于3 fi不要用直接比较数字因为在[ ]里会被当作重定向符号轻则判断失效重则把原本不该覆盖的文件给覆盖掉。这条经验代价不小我认为每个新手都值得记进笔记。2.3 循环for 和 while 什么时候该用谁第 12 天我同时尝试了for和while最后的理解是如果已知要处理的对象列表比如一批文件、一组 IP、几个磁盘分区用for最舒服如果不知道明确数量靠某个条件来控制循环比如“内存占用超过 80% 就继续检查否则退出”那用while更合适。一个最简单的for循环示范for file in /etc/*.conf; do echo 配置文件: $file done这段代码会遍历/etc目录下所有以.conf结尾的文件并把它们的路径打印出来。编写时要注意do和done是成对出现的漏一个就会报语法错。刚开始我把它们想象成一对括号每次写循环就先写下for...do...done的整体框架再往里面填内容这个习惯让我少犯了很多低级错误。while的典型场景则适合配合死循环来做持续巡检我先不在这里展开因为第 12 天更重要的是理解循环的基本结构。2.4 函数把脚本当成一个小管道很多人觉得函数是第 20 天才需要学的内容我却不这么看。今天写巡检脚本时如果不用函数我会发现脚本很长、逻辑很乱后面想加一个检查项就得在代码里来回找位置。用了函数之后脚本会变得像一个个小管道函数 A 负责采集磁盘信息函数 B 负责内存信息函数 C 负责输出结果。定义函数的格式很简单disk_check() { df -h } disk_check这里的技巧是函数名后面必须有()大括号里的内容就是函数体调用函数时直接写函数名就行。我第一次写成了function disk_check {}这是可以运行的但不同 Shell 环境下容易遇到兼容问题所以我更建议直接用最简洁的name() {}。函数里还可以用return返回退出码不过第 12 天先不纠缠细节能用函数把脚本结构梳理清楚比写出“一行超长长长长”的命令要重要得多。3. 完整实操写一个系统健康巡检脚本3.1 脚本需求拆解与准备环境我把今天的目标定义为“健康巡检”。刚开始我以为一个脚本把命令全部堆上去就行实际动手后发现必须先做需求拆解。我最终把脚本拆成了 4 个模块磁盘使用率检查找出哪个分区使用率超过 85%打印警告信息。内存使用情况检查输出当前剩余内存和总内存。CPU 负载检查读取/proc/loadavg判断最近 1 分钟负载是否过高。服务运行状态检查检查某个系统服务是否 active如果异常就提示。我使用的练习环境是一台虚拟机装的是 Debian 系列的某个主流发行版用的包管理器是apt。如果你用的是 Red Hat 系或 arch 系systemctl、df、free这些命令都是通用的不影响复现。3.2 分步实现磁盘、内存、CPU、服务状态第一步我创建了一个脚本文件touch health_check.sh chmod x health_check.sh vim health_check.shchmod x这一步其实非常重要。很多新手的脚本写完后无法执行就是因为没有给脚本加上执行权限。我第一天踩过这个坑后现在养成习惯创建.sh文件后顺手chmod x。脚本核心内容我分模块写先看磁盘部分#!/bin/bash disk_check() { echo 磁盘使用率 df -h | awk NR1 || $50 85 {print} }这里我用awk做了一个小判断第一行列标题照常输出后面行的使用率如果大于等于 85%就打印出来。$50这个写法很巧妙它会强制把awk读取到的字符串转成数字比如85%转成 85避免直接字符串比较的歧义。接下来是内存检查部分mem_check() { echo 内存使用情况 free -h }free -h会以人类易读的方式显示内存总量、已用量、空闲量。我本来想直接用awk提取剩余内存后来发现第 12 天先看整体输出更容易理解等第 15 天再进一步做数据提取也不迟。CPU 负载检查部分我读取了/proc/loadavg文件load_check() { echo CPU负载(1分钟) load$(cat /proc/loadavg | awk {print $1}) echo 当前负载: $load if [ $(echo $load 1.0 | bc) -eq 1 ]; then echo 警告: 负载偏高 else echo 状态: 正常 fi }这里用到了bc进行浮点数比较因为 Shell 原生只支持整数运算。bc是一个计算器命令我第 12 天才开始用属于合理的实战补充。如果不想装bc也可以用awk直接判断但整体来说bc的可读性更高。服务状态检查部分service_check() { echo 服务状态检查 systemctl is-active sshd }如果你是桌面系统没有安装 sshd可以换成其他服务比如cron。这段脚本的重点是演示“如何用命令拿到服务的运行状态”而不是纠结具体服务名。3.3 执行效果与调试记录我把脚本完整写入后先执行了一遍./health_check.sh第一次运行遇到的问题是脚本显示磁盘部分重复打印了所有分区但我其实只想看超过 85% 的分区。排查后发现是awk里那个NR1 || $50 85的问题——我的测试环境里没有分区超过 85%所以只输出标题但当时我在写测试时多放了一个正则条件导致多余的行被打印出来。改掉以后输出正常。第二次运行的结果大致如下 磁盘使用率 文件系统 容量 已用 可用 已用% 挂载点 /dev/sda1 495G 120G 351G 26% / 内存使用情况 total used free shared buff/cache available Mem: 7.6Gi 2.1Gi 3.2Gi 112Mi 2.2Gi 5.1Gi CPU负载(1分钟) 当前负载: 0.55 状态: 正常 服务状态检查 active看到这个输出的时候我第一次觉得“自学 Linux 真的有点门道了”。以前这些数据我要分别敲df -h、free -h、cat /proc/loadavg、systemctl is-active sshd才能拿到现在一个脚本全部搞定。这种正反馈对自学非常珍贵。4. 第 12 天必踩的坑与排查技巧4.1 变量赋值空格陷阱这个坑我开头提过但它值得一条独立清单。Shell 判断变量的语法非常严格我总结成一句话等号两边永远不要加空格。# 错误 name linux # 正确 namelinux出现command not found的时候不要只怀疑命令名写错了先检查变量赋值行的空格。这是我今天最快的一个排查经验全程不到 5 秒却可能让新手卡半小时。4.2 条件判断中的空格与引号条件判断[ ]是所有新手必踩的第二个坑。记住[后面必须有一个空格]前面也必须有一个空格。此外变量最好加双引号包起来否则一旦变量值为空Shell 会把test命令的多余参数吞掉产生难以理解的报错。下面这组对比应该能秒懂# 错误 if [ -d $dir ]; then echo 目录存在 fi # 正确 if [ -d $dir ]; then echo 目录存在 fi如果$dir为空错误写法会让条件判断变成一个空参数虽然大多数时候不会崩溃但结果不可控。这就是“加了双引号不是形式主义而是安全保护”的典型例子。4.3 脚本权限、解释器与换行问题“写了脚本却报权限 denied”大概是第 12 天出现频率最高的问题。解决方式很简单给文件加执行权限。但我今天想分享的坑不是这个而是换行符问题。如果你在 Windows 上用文本编辑器写脚本再传到 Linux 里执行很可能报$\r: command not found。这是 CRLF 换行符和 Linux 的 LF 换行符不一样导致的。解决方法也很简单sed -i s/\r$// health_check.sh或者直接用dos2unix health_check.sh。这个坑对纯虚拟机学习的人来说暂时不会遇到但如果你像我一样会偶尔把脚本复制到别的环境编辑早晚会碰到。另一个容易忽略的是解释器。脚本第一行必须写#!/bin/bash这行字决定了系统用什么解释器来执行你的脚本。如果不写系统会默认用当前的 Shell 去解释某些语法在sh下就有可能不兼容。4.4 定时任务执行脚本与手动执行结果不同今天的巡检脚本跑通之后我顺手设置了一个每天凌晨 2 点的定时任务然后遇到了一个很有意思的问题手动执行脚本一切正常定时任务执行却没有完整输出。排查后发现问题出在环境变量上。定时任务运行时没有加载当前用户环境下的 PATH 等变量导致systemctl或bc找不到命令。解决方案有两个在脚本开头强制声明完整路径比如/usr/bin/bc在定时任务里调用脚本时使用bash /home/xxx/health_check.sh并在脚本中先用export PATH/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin补全环境变量。我更推荐第二种因为一劳永逸。这个坑是今天最接近“真实生产环境”的一个也是最有价值的。5. 接下来第 13-18 天的方向与自学体会5.1 下一步学习计划用定时任务串起来第 12 天的巡检脚本已经能跑但我并不打算学到这里就停。我给自己安排的下一个阶段是把巡检脚本接入cron让它每天自动执行并把结果输出到日志文件。然后我会用第 13 到 15 天学习日志轮转、简单告警和软链接争取做到即使忘记手动运行系统也会自动完成巡检。我建议你也这样设置一个“以用带学”的路线。比如今天写完脚本明天的任务不是继续学新语法而是让脚本变得更“省事”加日志、加时间戳、加颜色输出再考虑更复杂的awk数据处理。这种顺着项目往下走的方式比漫无目的地看命令列表要有效得多。5.2 12 天自学下来我最想分享的三点经验第一脚本不是背出来的是拆出来的。很多人一看到脚本就想去背语法但我今天的体会是先写一个“丑”脚本能跑通再改比纠结优雅更重要。第二报错信息是自学最好的老师。我第 12 天至少有 8 次靠读报错信息找到原因比如command not found、syntax error near unexpected token这些提示虽然一开始看不懂但只要把关键词复制出来搜索很快就能定位问题。第三每天留出复盘时间。如果没有晚上那个 40 分钟的复盘我今天踩过的变量赋值、条件判断、权限、PATH 这些问题明天就会忘得干干净净。我个人在实操中最受益的习惯是准备一个专门的“坑位笔记”每遇到一个报错就记录三行内容——场景是什么、报错是什么、解决方式是什么。第 1 天到第 12 天下来这本笔记已经成了我最重要的 Linux 学习资料。

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询