Linux运维shell脚本实战:从骨架搭建到自检清单

发布时间:2026/9/17 6:04:04

Linux运维shell脚本实战:从骨架搭建到自检清单 简介《Linux运维必备工作常用shell脚本》是一份面向Linux运维工程师的实用Shell脚本参考文档适合具备一定命令行基础、希望将日常巡检与维护工作自动化的读者。文档围绕真实运维场景系统整理了日志错误过滤与统计、服务健康检查、网络连通性测试、旧文件清理与备份压缩、循环多文件操作、scp远程传输、用户home目录核查、日志实时监控与异常捕获以及自动化创建用户、进程检查与kill、服务器系统初始化配置等常见需求并配有可直接参考的脚本片段和简要注释。包体为单个PDF文件大小仅100KB内容精炼、便于随时查阅。该资源目前已有1164人学习下载既适合需要快速提升脚本编写效率的运维新手也可作为中高级运维人员的日常工作速查手册。整体结构清晰示例短小直接便于理解后按需调整复用。1. 为什么“Linux运维必备常用shell脚本”先要立规矩而不是背命令运维手里那份《Linux运维必备工作常用shell脚本.pdf》问题从不在于“不够全”而在于把它当成背书的材料。真正回到生产环境时你面对的不是“一条命令能不能跑”而是“这条命令在凌晨两点读写到日志里的内容是什么格式、退出码是多少、下一次执行时会不会污染上一轮结果”。同样一条df -h在终端里看和写进脚本里定时跑要求完全不一样终端里输出错了可以重敲脚本里错了就可能在监控页面上躺一整晚。所以这类资料的合理用法是把它当索引照着索引维护一套自己的脚本库每一条都带上日志、阈值、退出码和可重入的保护。这篇文章按“骨架 → 巡检 → 批量与备份 → 排障 → 自检”这条线把我平时怎么把这些脚本组合成一套可运维、可交接的shell脚本库完整拆开讲。这套东西适合两类人一是刚切到服务器运维、手里有一堆常用命令但还没形成脚本规范的Linux运维工程师二是做桌面运维助手或自动化运维转型的人需要把零散命令固化成能被cron和监控系统反复调用的固定工具。下面的代码都以bash 4为准默认系统是RHEL系或Debian系不需要额外安装重型依赖。2. 脚本骨架set -euo pipefail、日志函数和退出码是脚本库的地基2.1 让每个脚本自动带上 set -euo pipefail出现异常立即退出我见过的运维脚本里最常见的翻车现场不是逻辑写错而是“命令失败了脚本还在继续跑”。比如cd /data/app rm -rf logs如果cd失败rm 会删到当前目录。避免这类问题的第一步就是在每个脚本头部写死三行#!/usr/bin/env bash set -euo pipefail IFS$\n\tset -e只要脚本里有命令返回非零状态整体立即退出。代价是像grep没匹配到这种“正常失败”也会中断流程所以后续要用|| true或if grep显式兜底。set -u变量未定义就报错。典型收益是防止rm -rf $DIR/里DIR没赋值最后变成rm -rf /这种事故。set -o pipefail管道中任何一段失败都会让整条管道返回非零。没有它mysqldump | gzip里mysqldump崩了gzip照样成功备份却是个空壳。IFS$\n\t是把字段分隔符收缩成换行和制表符防止文件名里的空格被 for 循环拆开。这行配合set -u是脚本库地基里的地基建议做成模板文件而不是每次手打。2.2 日志函数统一输出格式排查时不用猜脚本多了以后最难受的是每份脚本打印日志的格式不一样。有人用echo有人用logger报警的时候很难归档。我一般会抽一个公共库文件比如在/opt/ops/lib.sh里放两个函数所有脚本都source它readonly APP_LOG/var/log/ops/$(basename $0).log log_info() { echo $(date %Y-%m-%d %H:%M:%S) [INFO] $* | tee -a $APP_LOG } log_error() { echo $(date %Y-%m-%d %H:%M:%S) [ERROR] $* 2 | tee -a $APP_LOG 2 }tee -a把内容同时送到终端和日志文件log_error里要先重定向到2否则错误信息和正常日志混在同一个输出流cron 里没法区分成功失败。日志文件的目录要提前建好脚本里可以加一句mkdir -p /var/log/ops不要等第一次报错才想起来目录不存在。2.3 退出码约定0是成功其他都是有具体含义的失败脚本被cron或监控平台调用时最终靠退出码判断成功与否。我习惯在前半部分定义一组退出码比裸数字好读readonly E_OK0 readonly E_PARAM2 readonly E_DISK_FULL3 readonly E_SERVICE_DOWN4常见错误码对应关系可以这样沉淀成一张表退出码含义使用场景0成功正常完成且数据有效1通用错误未分类异常2参数错误传入的参数数量或格式不对3资源不足磁盘、内存、容量触达阈值4服务异常端口不通、进程消失、依赖缺失调用方只要对照表就能定位大概方向。函数里return $E_PARAM脚本末尾exit $E_DISK_FULL监控系统拿到的不是一个没头没尾的“1”而是可以直接映射到告警文案的状态。骨架阶段不要追求代码量把这三个部分统一好后面写任何脚本都是往这个框里填肉。3. 巡检脚本磁盘、内存、CPU、进程存活一次跑完并输出结构化结果3.1 磁盘巡检脚本df加阈值比裸跑df靠谱得多运维巡检里最高频的是磁盘。df -h的毛病是输出给人看的脚本没法直接吃。我会写一个check_disk.sh接收一个阈值参数默认写到 80% 就告警#!/usr/bin/env bash source /opt/ops/lib.sh THRESHOLD${1:-80} df -P | awk -v thr$THRESHOLD NR1 { gsub(/%/, , $5) if ($5 thr) { printf DISK_ALERT mount%s used%s%%\n, $6, $5 exit 4 } }df -P是POSIX格式不会因为设备名过长而换行这是给脚本用的关键参数。awk 里用-v thr$THRESHOLD把shell变量传进来gsub去掉百分号后做数值比较。注意这里exit 4会直接结束awk而set -e会把 awk 的退出码4传给脚本刚好落到上面约定的E_DISK_FULL4。如果你用df -h写同样逻辑迟早会因为卷名里出现多余空格而误报。3.2 内存和CPU统计从 /proc 取数不装 sysstat有些最小化安装的机器没有free或者版本太旧我更推荐直接读/proc/meminfo它一定存在且格式稳定total$(awk /MemTotal/ {print $2} /proc/meminfo) avail$(awk /MemAvailable/ {print $2} /proc/meminfo) used_percent$(( (total - avail) * 100 / total )) if (( used_percent 90 )); then log_error memory used${used_percent}% exit 3 else log_info memory ok used${used_percent}% fiMemAvailable是内核 3.14 提供的字段它估算的是“在不触发交换的前提下还可分配多少内存”比used/total这种粗糙算法贴近业务体感。CPU 负载则读/proc/loadavg的第一列但要记得load average包含不可中断睡眠偶发偏高不一定代表CPU被打满。想看真实占用用top -bn1 | head -n5做一次采样更直观脚本里注意加-b批处理模式否则top会用交互界面输出乱码。3.3 服务进程与端口存活检查内存操作中不可忽略的一步进程检查按“端口优先于进程名”的原则设计。比如MySQLpgrep mysqld在服务僵死时仍可能返回成功探查TCP端口更可靠check_port() { local host$1 local port$2 if command -v nc /dev/null 21; then nc -z -w 3 $host $port /dev/null 21 else timeout 3 bash -c echo /dev/tcp/$host/$port /dev/null 21 fi } check_port 127.0.0.1 3306 log_info mysql alive || { log_error mysql down; exit 4; }nc -z -w 3是零数据探测并等待3秒不给服务写入任何业务数据适合巡检场景。没有nc的系统就用bash自带的/dev/tcp设备文件做TCP连接同样能达到目的。两者都失败时进程名检查可以作为兜底但不建议反过来。整个巡检脚本设计成“一个main函数串起多个check函数”每类检查输出一行机器可读的KEYVALUE文本之后无论是接Prometheus的textfile collector还是自己写解析都省事。4. 批量操作与备份for循环的坑、SSH批量分发和定时任务守护4.1 for循环的正确姿势数组和while read让步进可控shell脚本里for循环是高频操作而最常见的坑是变量遍历被空格拆开。要遍历一个目录下所有文件新手这样写for f in $(ls /var/log/*.log); do echo $f done这个写法一旦文件名里带空格$f就会被拆成两个。正确做法是用数组或find whileshopt -s nullglob for f in /var/log/*.log; do [[ -f $f ]] || continue echo $f done while IFS read -r line; do echo $line done (find /var/log -maxdepth 1 -type f -name *.log -print)shopt -s nullglob保证没有匹配文件时通配符展开为空数组而不是保留字面量导致误处理。while IFS read -r line里的IFS避免行尾空格被吞掉-r防止反斜杠被解释这两点是读取文件名时不可减的配置。用find时我发现很多人忘记-maxdepth 1结果递归处理了子目录里的同名文件批量操作时容易波及无关目标。4.2 批量SSH执行无论用expect还是ssh密钥先管好密码与登录安全对几十台上万台服务器批量执行命令我先检查现有基础设施如果已有堡垒机或配置管理平台就优先走它们如果必须用自己写的脚本第一选择是SSH密钥登录而不是expect里嵌明文密码。密钥登录的批量分发脚本骨架如下hosts(172.16.1.10 172.16.1.11 172.16.1.12) cmduptime df -h / for h in ${hosts[]}; do ssh -o ConnectTimeout5 -o StrictHostKeyCheckingno \ -o BatchModeyes opuser$h $cmd \ || log_error node $h failed doneBatchModeyes可以保证当你没有配置密钥或密钥不对时SSH不会停在那里交互式问你密码这在无人值守执行里极其重要避免一个卡住的输入把整批任务挂在第一台机器上。StrictHostKeyCheckingno只建议在首次批量接入时使用并且配合known_hosts校验否则等于自己放弃了中间人防范。如果你的执行环境实在只能密码登录用expect也要把凭证从外部配置读取并打码脚本本身不要出现password字样的明文参数。4.3 备份脚本tar打包、按时间轮转、再同步到远程定时任务要加锁备份脚本看着简单实际容易毁在“重复执行”上。上一轮还没跑完cron又拉起新一轮两边同时写同一个tar文件备份文件直接损坏。我的做法是给脚本加一个简单的flock文件锁exec 9/var/run/ops_backup.lock if ! flock -n 9; then log_error backup already running, exit exit 1 fi STAMP$(date %Y%m%d_%H%M%S) tar czf /backup/app_${STAMP}.tar.gz -C /data app/ find /backup -name app_*.tar.gz -mtime 7 -deleteexec 9文件打开一个持有文件描述符9的锁文件flock -n 9非阻塞尝试加锁失败说明另一个实例在跑直接退出。打好包后立即用find -mtime 7 -delete清理超过7天的旧备份这是最便宜的轮转策略。别在tar的源路径上写/data/app到了恢复场景还得想“当时相对路径是什么”-C /data把归档基准目录单独指定解包时直接落在当前目录/app下面路径行为可预期。如果还要推到远端用rsync -av --partial /backup/ backup-server:/backup/--partial保证中断后保留已传部分下次续传而不是从头来。定时任务里我一般写成10 2 * * * /opt/ops/backup.sh /var/log/ops/backup_cron.log 21这里21和缺一不可否则cron会额外给maillog发一封只有报错内容的信时间久了邮箱淹没问题反而不显眼。5. 日志与故障排查awk、sed、grep 排障组合及命令超时防护5.1 日志切割与清理先归档再删除避免磁盘被日志占满排查故障第一步是拿到日志但系统里堆了几GB日志时最需要的是把“一直在写的日志”和“可以归档的旧日志”分开。常见的logrotate配置之外手动处理时我习惯用find tar按天归档find /var/log/app -name *.log -mtime 1 -print0 \ | xargs -0 tar czf /backup/log/app_$(date %Y%m%d).tar.gz find /var/log/app -name *.log -mtime 7 -delete-print0搭配xargs -0让文件名里的空格、换行都不再是障碍。第二段-mtime 7 -delete删除的是归档后的源文件。想解压中文文件名乱码的问题根源通常是zip的编码和系统locale不一致unzip -O gbk可以指定编码归档阶段多用一个参数比事后解乱码省心。5.2 grep/awk/sed 在排障场景的常用组合把日志切片而不是全文翻线上排查日志时我一般按“先缩小时间范围再做字段提取最后聚合计数”的顺序而不是直接tail -n 1000纯靠肉眼。一段时间内某个接口的耗时分布可以这样切grep 2025-06-01 10: /var/log/app/access.log \ | grep -o cost[0-9]*ms \ | sort -t -k2 -n \ | tail -20grep -o只输出匹配的片段整个管道里的数据量骤减。如果要看错误码分布把grep -o换成sed -n s/.*status\([0-9]*\).*/\1/p | sort | uniq -c直接得到每个状态码的出现次数。awk 适合做字段抽取比如打印第7列的耗时配一个if ($7 3000) print $1, $7就完成了慢请求初筛。最后结合sed -n /2025-06-01 10:01:00/,/2025-06-01 10:02:00/p把窗口外数据滤掉整轮排查就不需要翻动大文件。5.3 给命令加超时和并发防止脚本卡死和清空负载脚本里最容易被忽略的坑是“命令不发返回”。磁盘有坏道、NFS挂载点无响应、DNS解析超时都会让脚本里去不返。统一给外部命令加timeouttimeout 10 ping -c 3 $target /dev/null 21 || log_error ping timeouttimeout 10让ping最多运行10秒超时即杀。这个习惯必须覆盖到ssh、curl、mysql等所有会发起外部连接的命令上否则一个巡检脚本可能因为某个远端服务假死而卡到cron下一轮启动最终拖垮调度。并发批量执行时xargs -P比各自更可控cat host_list.txt | xargs -P 10 -I {} ssh -o ConnectTimeout5 opuser{} uptime-P 10限制同时最多10个SSH连接-I {}把每一行内容替换到命令位置。没有并发控制时对200台机器一次性发起SSH源端的进程数和连接数会瞬间打满CPU没爆、负载先爆。观察这类故障只看ssh进程数量就能确认是并发失控。6. 用 shellcheck 和自检清单把脚本库变成可交接的资产脚本写完不等于能用能跑也不等于可维护。在把新脚本放进cron以前我固定跑两遍检查。第一遍是shellcheck它对bash的静态检查比人眼靠谱得多shellcheck -s bash -S warning /opt/ops/*.sh-S warning把告警级别设为warning以上才提示排除一批琐碎的style建议。最常见的两个告警是SC2086提示变量没加双引号这对应实际运行中的空格拆分问题SC2164提示cd后没检查是否成功——这就是开头说到的rm -rf事故源头。修完shellcheck后用shfmt -i 4 -ci -sr统一格式我倾向于缩进4空格-ci让case语句对齐更清晰-sr把重定向符号规范成 file而不是file 风格统一对交接非常重要。第二遍是格式自查。脚本文件必须是UTF-8无BOM行尾必须是LF。Windows下编辑过的脚本带着CRLFbash执行时会报$\r: command not found之类莫名其妙的错排查时直接浪费半小时。用file script.sh看输出或者sed -n l查看行尾控制符都能快速识别。自检清单我会固定在脚本库根目录的README里每个脚本必须有日志函数调用外部命令必须套timeout涉及删除和覆盖的路径必须是变量且经过存在性检查必须定义非零退出码含义必须用flock挡住并发执行。新脚本只有过完这五条才能提交到生产环境的/opt/ops/目录。这样一套体系下来那份PDF里的命令仍然全都在用但每一行都变成了有日志、有退出码、有超时保护的正式工具换人接手时不需要对着脚本猜当初的意图。本文还有配套的精品资源点击获取
延伸阅读

更多相关文章

2026/9/17 6:04:04

RK3568 SPI LCD的FrameBuffer驱动实战:从设备树配置到性能优化

1. 项目概述与FrameBuffer模式选型1.1 这个项目到底在做什么手头有一块RK3568的开发板,需要外接一块SPI接口的LCD屏,用来做系统状态显示和简单的交互界面。这应该是很多做嵌入式产品的工程师都遇到过的场景:主控性能足够强,但产品…

2026/9/17 5:59:04

网络工程师面试题全攻略:从协议原理到设备配置实战

简介:这是一份面向网络工程师岗位面试的PDF文档,内容基于CCNA/CCNP基础考查范围,围绕交换机数据转发、STP生成树、传统多层交换与CEF多层交换、DHCP配置与中继、静态/动态路由、有类与无类路由协议、RIP防环机制等高频考点,整理成…

2026/9/17 5:59:04

Excel数据如何建好知识库?Dify实战经验与检索优化指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/17 7:54:08

CommVault 备份 Oracle 实战:从安装到恢复验证全流程解析

简介:面向Linux环境下的Oracle数据库管理员,这份PDF是一份详细的CommVault备份恢复实操文档,从安装前准备、CommVault软件安装,到Oracle备份配置和灾难恢复,给出完整操作流程。全文基于NOCATALOG方式结合RMAN&#xff…

2026/9/17 7:54:08

工业旋转机械故障诊断:对抗性单域泛化与样本平衡技术

1. 项目背景与核心价值旋转机械作为工业领域的核心设备(如风力发电机、航空发动机、工业泵组等),其故障诊断的准确性直接关系到生产安全与经济效益。传统诊断方法面临两大核心痛点:一是实际工况下采集的训练数据往往来自单一工作域…

2026/9/17 7:54:08

光储电站经济性配置MATLAB工具解析与优化

## 1. 项目背景与核心价值在新能源占比不断提升的电力系统中,光储电站的经济性配置一直是行业痛点。去年参与某50MW光伏配储项目时,我们团队花了三周时间反复测算不同储能容量下的IRR变化,最终发现传统经验公式与实际运行数据存在15%以上的偏…

2026/9/17 7:54:08

从提示工程到Token效率:AI应用落地的完整链路与实践指南

1. 大会现场:PEC 2026释放了什么信号这两天我蹲在PEC 2026 AI创新者大会暨第三届提示工程峰会的现场,最大的感受是:口号从去年喊的“大模型能力决定上限”,悄悄变成了“Token效率决定落地”。会场主舞台的电子屏上,“赢…

2026/9/17 7:54:08

AI应用太累?用Agent自动化接住脏活,解放生产力

你有没有发现,自从认真开始用 AI,你自己反而更忙了?AI 确实负责了“创造”的部分——它写文章、出方案、生成代码、做图、剪视频,看起来无所不能。但真正消耗你时间和耐心的,往往是另外一些事:把 AI 生成的…

2026/9/17 7:49:07

agent-skills 实战指南:如何为智能体设计稳定可控的技能库

最近好几个团队都在折腾同一个问题:给智能体写技能时,到底怎么规划才能让模型稳定调用、代码好维护、扩展还不费劲。我在自己的项目里也反复改了好几版,踩了不少坑,正好借这个机会把 agent-skills 这套思路完整梳理一遍。这个东西…

2026/9/16 12:52:37

拯救者Y7000黑屏故障排查与维修实战指南

1. 项目概述:一台黑屏的拯救者Y7000,到底卡在哪一步? 联想拯救者Y7000系列笔记本,从2018年第一代搭载i5-8300H开始,到后来的i7-9750H、i7-10750H、i5-11400H,再到2023年款的R7-7840HS,它始终是学…

2026/9/17 0:03:13

WiFi密码安全测试:从原理到实战的字典暴力破解指南

1. 写在前面:我为什么要研究WiFi密码这件事先交代一下背景。我身边有不少朋友,家里的WiFi密码常年是"12345678"或者"88888888",问就是"好记"。直到有一次,隔壁邻居蹭网蹭到我家路由器后台都进不去&…

2026/9/17 0:03:13

redis-py服务控制与监控函数实战:从ping到slowlog的巡检指南

我用 redis-py 写了快五年的业务代码,坦白说,真正让我觉得这个客户端“像一个成熟工具箱”的,不是 get/set 那套基本操作,而是它那批专门做服务控制与状态监控的辅助函数。日常开发里,大家把redis.Redis(host..., deco…

2026/9/17 0:03:13

SpringBoot+Vue3实现中小企业设备管理系统开发实践

1. 项目概述与核心价值中小企业设备管理系统是制造业、服务业等领域的基础信息化工具。传统设备管理往往依赖Excel表格或纸质记录,存在数据孤岛、流程混乱、维护成本高等痛点。这套基于Java SpringBootVue3MyBatis的技术方案,通过前后端分离架构实现了设…

2026/9/16 22:55:57

USB Type-C PCB布局分区设计:电源、高速信号与PD协议全攻略

做硬件这行,Type-C接口算是典型的“看着简单,做起来全坑”的东西。光引脚就24个,高低速信号、电源、控制线全部塞在一个小小的连接器里,如果PCB布局不做规划,打样回来基本就是“插上没反应”、“高速掉线”、“静电一打…

2026/9/16 22:56:09

系统编程学习原型如何补齐稳定性边界

系统编程学习原型如何补齐稳定性边界预算有限时&#xff0c;我先优化明显多余的复制&#xff0c;而不是猜测性地换容器。用借用传递只读数据通常就能减少分配&#xff1a; fn parse(line: &str) -> Result<Item, Error> { /* ... */ }用基准确认热点确实在分配&am…

2026/9/16 22:56:16

雨花区哪家财务公司代理记账比较好?

在雨花区&#xff0c;企业处理财税事务常常面临诸多挑战&#xff0c;选择一家靠谱的财务公司至关重要。湖南巨勤财务管理咨询有限公司就是本地正规实体财税服务机构&#xff0c;深耕本地工商财税行业多年&#xff0c;熟悉当地工商局、税务局最新政策与申报流程。主营公司注册、…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
咨询二维码