尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
Linux运维基本功:25个必练的Bash脚本实战示例
1. 为什么我建议把这25个脚本当基本功来练1.1 脚本解决的是重复劳动而不是命令不会bash script 是 Linux 下绕不开的基本功。我刚用 Linux 那会儿觉得会敲几十条命令就算入门了后来发现自己每天都在重复同样的事情备份目录、查日志、看磁盘占用、手动重启挂掉的服务……一开始还能忍直到有一次连续三晚都花二十分钟在重复输入同一组 tar 命令我才意识到问题不在命令记不熟而在没有一个流程化的脚本把这些事情固化下来。如果你也处于这个阶段我的建议很直接别再去背第 101 条命令了把这25个常见脚本例子敲一遍你收获的会是解决问题的思路而不是某个命令的语法。这25个脚本覆盖了我日常使用频率最高的几类场景文件批量操作、日志分析、系统状态检查、交互式菜单、后台并行任务、定时执行。你可以先把它们当成模板抄走跑通了再改成适合自己的内容。1.2 练脚本的正确姿势先抄、再改、最后忘我见过不少朋友学脚本喜欢一上来就写原创脚本结果写了半天卡在引号和变量展开上最后放弃了。我的路线是先把别人写得好的脚本按原样敲到机器上跑通然后改成自己的工作目录、日志路径、告警阈值最后把它扔到一边凭理解重新写一遍。改的过程中你会遇到路径问题、引号问题、权限问题、管道退出码问题——这些坑才是真正的收获。练习环境方面本地虚拟机装个 Ubuntu 或 CentOS 就够生产服务器上练习不太安全。我早期是在一台多出来的测试机上练的后来发现虚拟机的快照功能更好用脚本写坏了直接回滚完全不慌。今天这篇文章里的脚本我在 Ubuntu 22.04 和 CentOS 7 上都跑过没有依赖某个发行版特有的东西你可以放心复制。2. 真正开工前先解决三个地基问题2.1 脚本头行与执行权限示例1几乎所有 bash 脚本的第一行都是#!/bin/bash它的作用是指定解释器。别小看这一行我曾经在一台默认 shell 不是 bash 的机器上跑脚本折腾了半天才反应过来是头行写错了。稳妥一点可以写成#!/usr/bin/env bash让系统去 PATH 里找 bash不过说实话在绝大多数 Linux 发行版上#!/bin/bash就够用Ubuntu、CentOS、Debian 都没问题。写完后要加执行权限否则脚本不会被认为是可执行文件chmod x myscript.sh如果你不想动权限也可以直接用解释器执行这样脚本本身有没有执行权限都无所谓bash myscript.sh这里有个容易踩的坑sh myscript.sh和bash myscript.sh不完全一样在部分系统上 sh 指向 dash语法兼容性有差异。凡是用了数组、[[ ]]、${var:-default}这类 bash 扩展语法的脚本一律用 bash 执行别用 sh否则大概率报错。2.2 set -euo pipefail示例2这是我在所有脚本里加的第一行重要性甚至超过 shebang。举一个真实场景早期我给线上服务写备份脚本中间某条 tar 命令因为磁盘空间不足失败了但脚本没在出错时停下来继续往下跑最后把一份残缺的备份当成成功结果打包发给了同事。那次之后我给所有脚本统一加了set -euo pipefail让脚本在出错时立刻退出#!/bin/bash set -euo pipefail # 中间任何命令出错脚本都会直接终止 echo 开始备份 cp /data /backup/data_$(date %F) echo 备份完成逐段解释一下这三个选项背后的逻辑set -e任何命令返回非0退出码脚本立刻终止。这能避免一个错误被后面几十行命令掩盖。set -u变量未定义就报错。拼错变量名导致复制了空目录、删了错误路径这类低级事故全被它挡下来。set -o pipefail管道看成整体中间任何一条命令失败都算整条管道失败。比如dd | tar没有 pipefail 时只要最后一条 tar 成功前面 dd 失败也会被认为成功。一开始用set -u可能会烦比如有些脚本依赖未定义变量插入默认值。但只要规范地写${var:-default}就不会误报这个习惯值得养成。2.3 用 bash -x 调试示例3脚本跑出不对的结果先别急着改逻辑先看它到底执行了哪些命令。加-x参数运行bash -x myscript.sh输出里每一行前面带的就是实际展开后的命令。比如你写了cp $SRC $DST-x会直接告诉你变量展开成了什么一眼就能看出路径是不是多了个空格或者变量压根没赋值成功。如果只调试某一段可以在脚本里临时插入set -x # 想观察的命令 set x这个技巧我每次排错都会用。日志看得多了你就会明白90% 的脚本问题不是语法而是变量展开的结果跟你的预期不一样。你觉得$LOG_DIR是/var/log/myapp实际它可能因为上一行 cd 命令变了路径-x一看就露馅。3. 文件与目录操作每天都要写的批量处理脚本3.1 批量重命名与循环取数示例4、示例5批量重命名是出现频率最高的需求。比如给一堆 txt 文件加上日期前缀#!/bin/bash for f in *.txt; do mv $f $(date %Y%m%d)_$f done这里有个非常关键的习惯变量一定要加引号尤其是$f。如果文件名里有空格不加引号会被拆成两个词mv 就会报错或者把文件移动到诡异的位置。另一个坑是*.txt匹配不到任何文件时$f会直接变成字面量*.txt字符串循环照样执行一次可能把文件重命名成奇怪的名字。更稳妥的写法是加一个存在性判断for f in *.txt; do [ -e $f ] || continue mv $f bak_$f done示例5是统计当前目录所有 .log 文件的总行数这段代码我在日志分析场景里改写过很多次#!/bin/bash total0 for f in *.log; do lines$(wc -l $f) total$((total lines)) done echo 所有日志总行数$totalwc -l $f这一步初学者容易写成wc -l $f那样会把文件名也打印出来用重定向输入就只输出数字。算术运算$(( ))是 bash 内置的写起来比 expr 清爽得多也更快。3.2 备份、清理旧文件、自动归档示例6、7、8带时间戳的备份是我用得最多的脚本没有之一。它同时解决了备份和清理旧备份两件事#!/bin/bash backup_dir/backup target/var/www/html stamp$(date %Y%m%d_%H%M%S) tar czf $backup_dir/www_$stamp.tar.gz -C /var/www html find $backup_dir -name *.tar.gz -mtime 7 -exec rm {} \;这段代码里最值得琢磨的是-C /var/www html的写法。它的目的是打包时去掉绝对路径让压缩包解压后直接是html/目录结构而不是恢复成一堆/var/www/html的完整路径。如果你不写-C别人解压你就会看到一路套娃的目录非常烦人。清理旧日志用的也是同一套路比如 nginx 日志保留30天find /var/log/nginx -name *.log -mtime 30 -exec rm {} \;担心删错的话先别直接进-exec把名单打出来看一眼find /var/log/nginx -name *.log -mtime 30 -print按扩展名自动归档示例8是另一个很常见的整理脚本。比如把 jpg、png、gif 分类放到不同目录#!/bin/bash for ext in jpg png gif; do mkdir -p archive_$ext mv -v *.$ext archive_$ext/ 2/dev/null || true done注意2/dev/null || true这组写法当某种扩展名在当前目录没有文件时mv 会报错并导致脚本中断加了这个保护之后脚本可以继续处理下一种扩展名。我在写这类脚本时默认都会考虑没找到文件这种分支否则脚本越写越脆。3.3 目录自动创建与配置文件引入示例9、10示例9是目录判断加创建常用于脚本运行前保证环境存在一句mkdir -p搞定mkdir -p $HOME/logs $HOME/data $HOME/tmp-p表示父目录不存在就一起建而且目录已经存在时也不会报错。很多脚本一上来就写if [ ! -d logs ]; then mkdir logs; fi其实完全没必要mkdir -p一句话就覆盖了两种场景。示例10是用 source 引入配置文件把脚本的参数和逻辑分离开这是我维护脚本时最受益的做法# config.conf THRESHOLD80 LOG_DIR/var/log/myapp BACKUP_ENABLEyes # main.sh #!/bin/bash source config.conf echo 阈值为 $THRESHOLD这样做的好处是不同机器上路径不同、阈值不同只需要改配置文件脚本本体一行不用动。我手里有两台测试环境和一台生产环境就是靠三份 config 文件区分开的脚本永远同一份改配置的风险远小于改脚本。4. 文本处理与系统巡检运维中真正的刚需脚本4.1 日志IP统计与错误提取示例11、12日志分析是 awk、sort、uniq 三大将的主场。统计访问量最大的十个 IP这是每个 Web 运维都绕不开的需求#!/bin/bash awk {print $1} access.log | sort | uniq -c | sort -rn | head -10思路拆开看awk {print $1}取出第一列默认是 IP前提是你的 access log 字段顺序标准sort把相同 IP 排到相邻位置uniq -c统计重复次数sort -rn按数字逆序排列最后head -10取前十。管道里每一步都简单组合起来就是非常漂亮的统计工具。我第一次跑出这个结果时真的有一种原来几行字就能搞定报表的震动。如果要提取 ERROR 行并定位行号示例12的写法是grep -n ERROR app.log | tail -50如果日志文件很大别直接对全文件 grep那会一次读入大量数据。先看文件大小ls -lh app.log # 如果超过几百MB先按时间范围过滤 awk $0 2025-01-01 10:00:00 {print} app.log | grep ERROR这是实践中特别常见的问题日志太大grep 一次卡了半天。学会用 awk 做时间范围裁剪内存占用会降一个量级几十 GB 的日志也能轻量扫。4.2 端口、磁盘、内存与负载巡检示例13、14、15、16端口存活检查示例13常规写法是用 ss 或 netstat我一般这样写#!/bin/bash port8080 if ss -tln | grep -q :$port ; then echo 端口 $port 正常监听 else echo 端口 $port 没有监听 figrep -q是静默模式不加-q会在屏幕上乱跳匹配到的整行内容。注意 grep 的模式里:$port 后面带了一个空格这是为了不让8080匹配到18080这种端口号。这个细节很多人会忽略你排查半天以为是服务挂了其实是匹配到了别的端口。磁盘空间告警示例14是另一个高频巡检项#!/bin/bash threshold80 usage$(df -h / | awk NR2 {print $5} | tr -d %) if [ $usage -gt $threshold ]; then echo 根分区使用率 $usage% 超过阈值 $threshold% | mail -s 磁盘告警 opsexample.com fi有些朋友问为什么不直接df -h自己看因为当你有十几台服务器时你要的是脚本扫一遍把超过阈值的机器列出来推给你而不是一台一台登录上去拿眼睛盯。内存和 CPU 占用前五的进程示例15用 ps 加排序就行echo 内存占用前5 ps aux --sort-%mem | head -6 echo CPU占用前5 ps aux --sort-%cpu | head -6head -6是因为第一行是表头真正的进程从第二行开始。如果想提取纯进程名和占用率再加一层 awkps aux --sort-%cpu | awk NR1 NR6 {print $11, $3%}系统平均负载告警示例16是对多核服务器很有价值的检查项#!/bin/bash load$(cat /proc/loadavg | awk {print $1}) cores$(nproc) if [ $(echo $load $cores | bc) -eq 1 ]; then echo 负载 $load 超过核数 $cores fi这里用 bc 做浮点比较因为负载可能是12.56这种小数shell 自带的整数比较处理不了。如果你的阈值是整数直接[ $load -gt 8 ]就行不用引 bc。5. 让脚本有人味菜单、确认和参数解析5.1 select 菜单与 read 确认示例17、18脚本不光是给人手动跑的命令行工具很多时候你需要交互。比如一个多选项的发布脚本用 select 天然生成菜单自动编号、自动校验输入#!/bin/bash echo 请选择要执行的操作 select action in 备份 清理日志 重启服务 退出; do case $action in 备份) echo 执行备份... ;; 清理日志) echo 执行日志清理... ;; 重启服务) echo 执行服务重启... ;; 退出) break ;; *) echo 无效选项 ;; esac doneselect 的好处是整个菜单逻辑不用自己写 while 循环和编号逻辑它默认会显示1) 备份 2) 清理日志...用户输了数字你拿到的是对应的字符串。不加 break 的话选完一项会继续返回菜单这在某些配置场景下很顺手。危险操作前加一个确认示例18我每次写脚本都会强调。下面这个例子保护过我一次#!/bin/bash read -p 确认要删除 /tmp/testdir 吗输入 yes 继续 answer if [ $answer ! yes ]; then echo 已取消 exit 1 fi rm -rf /tmp/testdirread -p是提示输入后面比对时answer两边加引号是为了防止用户直接敲回车跳过输入变量为空导致[语法报错。那次我差点在生产目录上执行 rm -rf就是加了确认才拦住手滑。5.2 getopts 解析命令行参数示例19脚本用久了你会希望支持-d指定目录、-v显示版本号这类的规范化参数。getopts 是 bash 自带的标准做法不需要额外安装任何包#!/bin/bash quiet0 dir/tmp while getopts qd:v opt; do case $opt in q) quiet1 ;; d) dir$OPTARG ;; v) echo Version 1.0.0 ;; *) echo Usage: $0 [-q] [-d dir] [-v] exit 1 ;; esac done echo quiet$quiet dir$dir注意 getopts 的写法d:表示 d 后面必须跟参数而v后面没有冒号表示 v 只是个开关。写错冒号位置是新手最容易踩的坑。$OPTARG用来取参数值而且它每次循环都会被更新所以你一定要立即存进自己的变量比如这里的dir$OPTARG别想着之后再去读$OPTARG。6. 组合拳并行、守护、定时与输出格式化6.1 CSV处理与后台并行任务示例20、21日常数据处理经常会碰到 CSV。用 awk 按逗号拆字段是示例20的基础用法#!/bin/bash # 输出第1列和第3列 awk -F, {print $1, $3} data.csv # 只统计第2列大于100的行数 awk -F, $2 100 {count} END {print count} data.csv-F,指定字段分隔符为逗号。但要说清楚边界如果 CSV 里含有带引号、带逗号的字段awk 是没法做完整 CSV 解析的这种场景建议直接用 Python 的 csv 模块。工具选型上要有点自知之明脚本不是万能的分析多列结构化数据时我一般会顺手换成 Python。多个独立任务并行跑示例21最典型的就是同时压缩多个目录的日志#!/bin/bash ( tar czf logs1.tar.gz /var/log/nginx ) ( tar czf logs2.tar.gz /var/log/mysql ) wait echo 两个打包任务都完成了把任务丢到后台wait等所有后台任务结束。比串行快一倍以上尤其适合备份、压缩这种高耗时且互不依赖的任务。如果要控制并发数量比如最多同时跑3个任务#!/bin/bash max_jobs3 for task in $(seq 1 10); do ( echo 任务 $task 开始 sleep 2 ) if [ $(jobs -r | wc -l) -ge $max_jobs ]; then wait -n fi done waitjobs -r统计正在运行的后台任务数够了就wait -n等其中任意一个结束。这个写法在几十个任务批量处理时很管用不会一次性把机器资源吃满。6.2 文件存在性判断与服务自动拉起示例22、23脚本经常要判断文件或目录是否存在示例22就用四个最常用的测试操作符if [ -f /etc/nginx/nginx.conf ]; then echo 配置文件存在 fi if [ -d /var/log/nginx ]; then echo 日志目录存在 fi-f判断文件、-d判断目录此外还有几个高频操作符我整理成了一张表方便你快速查阅操作符判断内容典型场景-e路径是否存在文件或目录先确认目标再处理-f是否存在且为普通文件检查配置文件-d是否存在且为目录检查日志目录-x是否存在且可执行检查可执行文件-w是否存在且可写检查日志/临时目录权限-z字符串是否为空校验参数-n字符串是否非空校验参数做安装脚本时这几个判断几乎必用能避免很多文件不存在但脚本硬着头皮往下走的问题。服务进程守护脚本示例23我维护过一套非常朴素的版本思路是在定时任务里每分钟检查一次进程是否存在#!/bin/bash if ! pgrep -f myapp.jar /dev/null; then echo myapp 进程不存在重新启动 /opt/myapp/start.sh /var/log/myapp_restart.log 21 fi把它写进 crontab每分钟执行一次就是一个不依赖 systemd 的简易守护。生产环境其实更推荐 systemd 的Restartalways但有些边缘工具、临时启动的进程或者没注册成 systemd 服务的旧环境这个脚本非常管用。注意pgrep -f匹配的是完整命令行这样才能区分路径不同、名字相似的进程。6.3 crontab 定时执行与输出重定向示例24定时执行是脚本上生产环境的最后一公里。拿前面的磁盘检查脚本举例加入 crontab*/5 * * * * /root/scripts/disk_check.sh /var/log/disk_check.log 21这里是追加输出不是覆盖21是把标准错误也并进同一个日志。如果你漏掉21脚本报错信息只会在 cron 的系统邮件里躺着查起来非常费劲。我通常还会在脚本里加一行日期标记让每次输出在日志里都有明显分隔echo $(date %F %T) 磁盘巡检开始 /var/log/disk_check.log没有这行的话连续的执行记录混在一起你根本看不出哪个告警是哪天发的时间久了日志就变成了天书。6.4 用 printf 生成格式化报表示例25最后一个例子很朴素但真的很实用把巡检结果输出成对齐的表格比如列出一批目录各自占用的空间#!/bin/bash printf %-20s %10s\n 目录 占用(MB) for d in /var/log /var/lib /home; do size$(du -sm $d | awk {print $1}) printf %-20s %10s\n $d $size done%-20s是左对齐20个字符%10s是右对齐10个字符。用 printf 而不是 echo 拼接输出会非常整齐重定向到文件后就能直接当报表看比手工调空格舒服得多。脚本不可能每次都要人盯着有了格式化的输出后续无论是发邮件、写监控平台还是人工巡检信息都好读得多。我在自己服务器上跑这套脚本已经大半年最大的体会是别指望一次写对也别指望脚本能覆盖所有情况。每个星期我都在现有脚本上加一点小功能要么某个目录的位置改了要么告警通道从邮件换成了别的通知方式。写完一个脚本的价值不在于它今天能用而在于它还能被你持续改进。你现在敲的每一段代码都是给未来的自己省下的时间。
RELATED

相关推荐

命令行纠错神器 thefuck:从安装到自定义规则的完整指南

命令行纠错神器 thefuck:从安装到自定义规则的完整指南

你有没有过这种经历:在终端里敲了一长串命令,结果手滑把git push写成git pu,或者把python拼成pythno,回车之后只能看到一堆刺眼的command not found。这时候只能咬着牙把命令重新敲一遍。说实话,在遇到 thefuck 之前&a…

📅 2026/10/7 16:43:21
Springboot+Vue在线点餐系统:从环境搭建到答辩升级的完整拆解

Springboot+Vue在线点餐系统:从环境搭建到答辩升级的完整拆解

简介:这套基于Spring Boot和Vue的在线点餐系统源码包,定位为计算机专业毕业设计级项目,适合用于毕设答辩、期末课程设计或就业项目练习。系统按前后端分离思路组织业务模块,覆盖管理员与用户信息管理、商品类型维护、订单处理、广…

📅 2026/10/7 16:38:21
心内科RAG与多智能体协同:构建可追溯的智能诊断系统

心内科RAG与多智能体协同:构建可追溯的智能诊断系统

简介:本资源面向医疗人工智能方向的研究者、算法工程师与心内科临床信息化开发者,提供一套基于检索增强生成(RAG)与多智能体协同架构的心内科疾病智能诊断系统开发项目。项目围绕心电图、超声心动图、生化指标等临床数据&#xff…

📅 2026/10/7 16:38:21
MORE NEWS

更多资讯

📰

Diginex为什么收购碳核算平台Plan A · 青绿蓝

2026年初,Diginex完成对欧洲碳核算平台Plan A的收购,交易对价约5500万欧元。据两家公司介绍,此次新收购将结合Diginex的ESG报告能力与Plan A的碳核算和脱碳技术,使得能够提供一个规模化、集成的可持续发展平台,旨在连接…

📰

基于SpringBoot的新乡市流浪动物救助系统 数据分析可视化大屏_5dpcz21t

目录同行可拿货,招校园代理 ,本人源头供货商项目背景与目标系统功能模块数据分析可视化大屏设计核心指标展示(5dpcz21t)技术架构与实现数据安全与隐私保护项目成果与应用价值项目编号说明项目技术支持获取博主联系方式 源码获取详细视频演示 &#xff1a…

📰

蓝牛仔与百褶裙:亚洲成年时装的九种光线练习

五幅并列预览;正文包含九张独立生成的完整人物图。 摘要| 同样是蓝色紧身牛仔裤和成年学院风短百褶裙,九个场景可以拥有九种气质。本文用九位20—22岁的虚构亚洲成年女性,拆解脸与发型、焦段、环境反射和自然动作如何让高清提示词…

📰

HarmonyOS 7 FlexDesk:FoldStatus折叠态与编辑草稿保持

03 把 FlexDesk 从几个固定宽度推进到了真实多窗口。 一轮测试里,窗口经历: 920760 → 612760 → 480610 → 360520 → 612760 → 920760收到 18 个 windowSizeChange,通过 48ms 合并成 6 次业务提交,详情面板和工具栏按密度降级&…

📰

基于SpringBoot的减肥减脂训练营管理系统设计与实现_2nld341d

目录同行可拿货,招校园代理 ,本人源头供货商项目背景与目标系统核心功能模块技术架构与实现数据模型设计要点安全与性能优化应用场景与价值项目扩展方向项目技术支持获取博主联系方式 源码获取详细视频演示 :同行可合作点击我获取源码->获取博主联系方式->进我…

📰

免费转换Word软件推荐!零基础轻松搞定各类文档转换

日常学习、办公中,我们经常会遇到文档格式转换的难题,尤其是PDF、图片转可编辑的Word文档。市面上转换工具五花八门,很多要么收费、要么带水印、要么转换效果极差,乱码、排版错乱问题频发。今天给大家整理了真正免费、好用、无套路…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬