尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

279个开箱即用Shell脚本:从落地、选型到生产级改造避坑指南

279个开箱即用Shell脚本:从落地、选型到生产级改造避坑指南 简介汇总279个可直接投入使用的Shell脚本应用集覆盖DDoS攻击IP自动屏蔽、Linux系统邮件告警、MySQL数据库单/多循环备份、Nginx访问日志按天切割与深度分析、网卡实时流量监控等高频运维场景。脚本逻辑清晰、关键命令注释完整适合Linux/Unix系统管理员、运维工程师及希望提升自动化能力的初中级学习者参考可结合实际业务需求修改后部署。资源包内共1个PDF文档体积4.69MB便于快速浏览、检索与离线学习当前已有154人学习下载。内容不仅有现成脚本代码还梳理了日期获取、日志分析、iptables策略、mysqldump备份、cron定时任务等核心技术点帮助读者理解脚本背后的设计思路与排错途径。对于需要快速构建服务器安全防护、数据库灾备和日志管理体系的团队这份资料具备较高实用价值。1. 279个开箱即用的shell脚本治好的是“重复劳动”焦虑不是“复杂问题”执念第一次拿到“279个开箱即用的shell脚本”压缩包时我的第一反应是“这么多八成有摆设”。翻完关键脚本后发现它的价值不在单个脚本多聪明而在于把巡检、日志、备份、网络检查这些最高频的运维场景统一成可以直接跑的形态。2024年新版脚本风格更干净变量、函数、退出码的约定更一致这对批量投入使用的人来说反而最值钱。这套东西适合日常维护几十台服务器的运维、刚接手机器又不想从零养脚本库的开发者也适合交付时快速凑齐基础检查项的人。它解决的是重复劳动不是复杂问题。下面按“怎么落地、怎么选、怎么改、坑在哪”的顺序把这套脚本真正用起来。2. 压缩包到手怎么落地目录规划、环境准备和首次运行拿到279个脚本的压缩包之后第一件要做的事不是立刻翻代码而是先把目录结构立起来。脚本集合最大的隐患就是目录乱脚本放在顶层、配置文件散落各处、日志不知道写到哪里一旦跑起来根本没法维护。我一般会首先在服务器上建一个独立目录比如~/ops/shell-lib把整个集合按“可执行脚本、公共函数、配置文件、日志、备份产物”拆成五块。2.1 拿到手先定位先看目录树和说明文档先把压缩包解开然后用tree -L 2看结构第一时间确定三件事脚本是不是按功能分子目录了、有没有公共函数文件、有没有内置的说明文档。很多脚本集合表面有279个文件实际有效脚本只有两百多剩下的是配置文件、空目录、说明文档甚至有几个是同一个脚本的旧版本。mkdir -p ~/ops/shell-lib cd ~/ops/shell-lib # 解压指令要和你实际拿到的包名一致 tar xzf shell-scripts-2024.tar.gz # 看两层目录先摸清结构再动手 find . -maxdepth 2 -type f | head -50这段代码的作用是先把环境立起来。mkdir -p保证目录不存在时自动创建后面所有脚本都能在这个公共目录里启动。find加上maxdepth 2是为了先看前两层避免一次性输出太多文件反而看不清结构。解压之后我建议把包里的说明文档先翻一遍重点看作者声明的依赖项、Linux发行版兼容性、有没有说明默认安装路径这些信息比脚本本身更能决定你能不能在一小时内跑通。2.2 环境准备先确认本地有没有这些默认依赖279个脚本不可能都只用原生的bash。凡是涉及网络、磁盘、数据库、文本处理的脚本多少都会依赖外部命令最常见的是curl、grep、awk、sed、gzip、df、mysqldump、jq。跑全套之前我建议先做一次依赖盘点缺什么补什么避免脚本跑到一半才报“command not found”。# 一键检查常用依赖是否存在 for cmd in bash curl grep awk sed gzip df jq mysql mysqldump bc getopt; do if command -v $cmd /dev/null 21; then echo [OK] $cmd else echo [MISSING] $cmd fi done这段代码的意义不是挨个执行which而是用command -v做一次快速扫描。command -v返回0表示命令存在非0表示缺失比which更可靠因为which在某些精简系统里本身可能就不存在。输出里凡是出现[MISSING]的就是你在跑对应脚本之前必须先处理的。比如jq缺失JSON解析类的脚本就跑不了mysql缺失数据库备份脚本就会在执行时直接退出。2.3 把 bin 目录加进 PATH让脚本可以被直接调用不把脚本加进 PATH 的后果是你每次都要bash /完整/路径/脚本.sh这非常累而且脚本里的人相对路径一旦写错就会翻车。常见做法是在~/.bashrc里增加环境变量把脚本的核心目录固定下来再把可执行脚本所在的 bin 目录加进 PATH。cat ~/.bashrc EOF # shell脚本库环境变量 export OPS_HOME$HOME/ops/shell-lib export OPS_CONF$OPS_HOME/conf export OPS_LOG$OPS_HOME/logs export PATH$OPS_HOME/bin:$PATH EOF source ~/.bashrc # 验证是否能直接找到脚本 command -v disk_check || echo 还没找到检查 PATH 配置这里用EOF而不是EOF是有意的带引号的 EOF 能防止$HOME、$OPS_HOME在追加时被展开确保变量是写进文件里、而不是写成固定的当前目录值。source之后新开的终端也会生效。PATH 加在靠前位置是防止系统里同名命令覆盖脚本库。2.4 跑通第一个脚本先选一个副作用最小的脚本验证环境想验证整个环境是否正常最快的办法是跑一个只读类脚本比如磁盘空间检查或系统信息收集脚本。这种脚本没有删除操作、不写外部文件跑挂了也不影响系统。以磁盘检查脚本为例你只需要传一个阈值参数进去# 阈值设成90意思就是超过90%才告警 bash bin/disk_check.sh 90 echo 退出码$?跑完你会发现脚本输出可能只有一行也可能有格式化表格更重要的是退出码。很多脚本都会约定0为正常、非0为异常。在第一次跑通之后我建议你观察一下它的输出格式是纯文本、还是带颜色、还是能输出 CSV。这一步看起来不起眼但后面你要接告警或自动化平台时输出格式决定了你要不要加一层解析。3. 279个脚本按场景怎么选巡检、日志、备份、网络四类先看哪几个脚本集合一多最容易犯的错是把时间花在“把所有脚本都读一遍”上。我的建议是反过来先确定你自己手头最痛的场景再按场景去翻对应脚本。绝大多数合集里的脚本都能归到四类系统巡检、日志处理、数据库备份、网络连通性检查。每一类的考察重点不一样下面分别说。3.1 系统巡检类先看指标采集范围再看输出格式系统巡检类脚本通常是这个合集里数量最多的一类涵盖CPU负载、内存占用、磁盘容量、进程数、登录失败次数等等。挑选时我只看两点第一是指标采集是否用对了命令第二是结果是否结构化。# 一个典型的巡检脚本骨架采集磁盘使用率并输出 CSV #!/usr/bin/env bash set -Eeuo pipefail echo filesystem,use_percent,mount_point df -h | awk NR1 { gsub(%, , $5); print $1,$5,$6 }这段代码展示了巡检脚本的通用套路。set -Eeuo pipefail让脚本在遇到未定义变量、管道失败时立刻退出避免错误被吞掉。df -h输出第一行是标题NR1跳过标题行gsub把百分比后面的%去掉最后拼成CSV。你拿到巡检脚本时重点看有没有类似的“可解析输出”设计。如果一个巡检脚本只是打印一堆字符串没有分隔符那它更适合人看不适合接自动化平台。3.2 日志处理类切割、归档、统计三件事边界条件完全不一样日志脚本在279个集合理通常也占不小比例。按天切割是最常见的需求。挑日志脚本时要特别留意三件事文件名后缀怎么生成、是否跳过正在写的内容、保留天数由什么参数控制。# 日志切割脚本按天归档并按保留天数清理旧日志 #!/usr/bin/env bash set -Eeuo pipefail LOG_DIR${1:-/var/log/myapp} KEEP_DAYS${2:-7} if [ ! -d $LOG_DIR ]; then echo [ERROR] 目录不存在: $LOG_DIR 2 exit 2 fi # 将 *.log 原地压缩为 *.log.20240101.gz find $LOG_DIR -maxdepth 1 -type f -name *.log -print0 | while IFS read -r -d f; do gzip -S .$(date %Y%m%d).gz $f done # 找到超过保留天数的 .gz 文件并删除 find $LOG_DIR -maxdepth 1 -type f -name *.gz -mtime $KEEP_DAYS -delete这段代码把切割和清理分成两步。参数化设计让路径和保留天数可以在调用时传${1:-默认值}的写法保证不传参也不会直接报错。-print0配合read -r -d 是为了处理文件名里有空格的情况这一步在日志目录里特别重要很多日志文件名都带空格或特殊字符。gzip -S指定压缩文件后缀-mtime $KEEP_DAYS表示只看修改时间超过N天的文件。你拿到合集里的日志脚本时先确认它用的是-print0还是普通的-exec。如果是普通写法且没做过滤遇到带空格的文件名大概率会翻车。3.3 数据库备份类先看备份用的命令、压缩方式、恢复脚本有没有配齐数据库备份脚本是风险最高的一类因为它的运行结果直接影响可用性。这类脚本我建议你只信“能恢复的备份”也就是备份完一定要有办法验证。选型时先看它用的是mysqldump、pg_dump还是文件系统快照方式再看有没有配套的恢复脚本。# MySQL 备份脚本骨架按库导出并压缩 #!/usr/bin/env bash set -Eeuo pipefail DB_USER${DB_USER:-backup_user} DB_PASS${DB_PASS:-} DB_NAME${1:-} BACKUP_DIR${2:-/var/backups/mysql} if [ -z $DB_NAME ]; then echo 用法: $0 数据库名 [备份目录] 2 exit 2 fi STAMP$(date %Y%m%d_%H%M%S) mkdir -p $BACKUP_DIR mysqldump --single-transaction -u$DB_USER -p$DB_PASS $DB_NAME | gzip $BACKUP_DIR/${DB_NAME}_${STAMP}.sql.gz echo 备份完成: $BACKUP_DIR/${DB_NAME}_${STAMP}.sql.gz数据库脚本最重要的参数是--single-transaction它保证备份期间不锁表在线备份时尤其关键。用户名和密码通过环境变量传入而不是写死在脚本里这是接手任何备份脚本时最应该先改的地方。备份完成后我会额外跑一次gzip -t来验证压缩包完整性再决定要不要保留这个脚本作为日常任务。3.4 网络与连通性检查以退出码和超时为准别只看输出网络类脚本和其他脚本最大的不同是它的执行结果受到外部环境干扰丢包、超时、DNS解析失败都可能让输出变得不可信。挑这类脚本时重点看有没有设置合理超时以及是否以退出码作为判断依据。# 连通性检查带超时并输出结构化结果 #!/usr/bin/env bash set -Eeuo pipefail TARGET${1:-8.8.8.8} COUNT${2:-3} TIMEOUT${3:-2} if ping -c $COUNT -W $TIMEOUT $TARGET /dev/null 21; then echo reachable exit 0 else echo unreachable exit 1 fi这段代码把输出和退出码绑在一起正常时输出reachable并返回0失败时输出unreachable并返回1。-W是超时秒数-c是发包数量。注意ping的参数在 Linux 和 macOS 上不一样macOS 用的是-t你如果脚本库里混用了这两个参数到了另一台机器上就会直接报错。这类脚本还有一点要注意就是不要把 ICMP 连通性和服务可用性混为一谈端口通不通是另一层问题。4. 挑三个脚本做生产级改造参数化、配置化、退出码一个都不能少279个脚本里真正能“开箱即用”的估计只有一半多另外一半要么是示例、要么是某个特定环境的写法。我的经验是与其把这279个都用一遍不如挑三个最常用的改造到能直接进生产。改造的目标很简单参数能传、配置能改、退出码能信。4.1 日志切割脚本改造把路径和保留天数抽成参数先改造日志切割脚本。原始脚本很可能把路径写死在文件里比如LOG_DIR/var/log/nginx。这种写死的问题是你复制到新机器上就必须打开文件改很容易改错。改造后应该支持两个参数日志目录和保留天数。#!/usr/bin/env bash # 按天切割日志保留 N 天 # 用法: log_rotate.sh 日志目录 [保留天数] set -Eeuo pipefail LOG_DIR${1:?必须指定日志目录} KEEP_DAYS${2:-7} if [ ! -d $LOG_DIR ]; then echo [ERROR] 目录不存在: $LOG_DIR 2 exit 2 fi # 第一步压缩现有 *.log find $LOG_DIR -maxdepth 1 -type f -name *.log -print0 | while IFS read -r -d f; do gzip -S .$(date %Y%m%d).gz $f done # 第二步清理超过保留天数的压缩包 # 注意-mtime 的数值是“超过 N 天”保守起见可以加 1 find $LOG_DIR -maxdepth 1 -type f -name *.gz -mtime $((KEEP_DAYS1)) -delete echo [OK] $LOG_DIR 切割完成保留 $KEEP_DAYS 天这次改造有三个关键变化。第一个是${1:?必须指定日志目录}这个写法会在参数为空时报错并退出避免后续所有命令拿空值去执行。第二个是KEEP_DAYS的默认值7天调用者不传也能跑。第三个是删除条件用了$((KEEP_DAYS1))也就是保留N天多一点防止刚切割完的文件因为时间边界被误删。实践中最容易翻车的就是这个保留天数边界建议按“多留一天”来改删文件条件。4.2 磁盘告警脚本改造阈值参数化告警通道和检测逻辑分离磁盘告警脚本是另一个高频改造对象。最初的版本往往只负责“检测加打印”能不能真正告警取决于你把它接到哪里。我习惯把告警动作单独拆出去检测脚本只负责判断和输出告警逻辑通过回调函数或环境变量来指定。#!/usr/bin/env bash # 磁盘使用率告警阈值作为参数 # 用法: disk_alert.sh [阈值] [文件系统] set -Eeuo pipefail THRESHOLD${1:-80} FILESYSTEM${2:-/} USAGE$(df -h $FILESYSTEM | awk NR2 {gsub(%,,$5); print $5}) if [ $USAGE -ge $THRESHOLD ]; then echo [ALERT] $FILESYSTEM 使用率 ${USAGE}% 超过阈值 ${THRESHOLD}% # 告警通道由环境变量决定不在脚本里写死 # 调用侧示例: ALERT_CMDcurl -s -X POST http://alert-server/api if [ -n ${ALERT_CMD:-} ]; then $ALERT_CMD $FILESYSTEM $USAGE fi exit 1 fi echo [OK] $FILESYSTEM 使用率 ${USAGE}% exit 0改造的重点是把“告警方式”从脚本里摘出去。你在这台机器上可能想发HTTP请求到告警平台在另一台机器上只想写日志如果脚本写死了告警方式就很难复用。用ALERT_CMD环境变量把告警命令交给调用者定义脚本本身只做检测和判断。这里没有给$ALERT_CMD加引号是刻意让 shell 按空格分词把命令和参数拆开这种写法对安全边界有要求所以注释里写清楚了调用侧负责定义可信命令。4.3 批量执行器改造处理空行、注释、引号防止命令被拆碎批量执行器的作用是从一个主机列表文件里逐行读服务器然后统一执行命令。这种脚本看起来简单但最容易出问题的是文件读取逻辑。没有经验的写法是for i in $(cat list)一旦列表里有空格或空行处理逻辑就会崩。更稳妥的是用while read配合IFS。#!/usr/bin/env bash # 批量执行器从文件逐行读取主机并执行命令 # 用法: batch_exec.sh 主机列表.txt [命令] set -Eeuo pipefail HOSTS_FILE${1:?必须指定主机列表文件} CMD${2:-uptime} if [ ! -f $HOSTS_FILE ]; then echo [ERROR] 文件不存在: $HOSTS_FILE 2 exit 2 fi # 逐行读取跳过空行与 # 开头的注释行 while IFS read -r host || [ -n $host ]; do case $host in |\#*) continue ;; esac echo $host ssh -o ConnectTimeout5 -o BatchModeyes $host $CMD done $HOSTS_FILE这段代码里有三个关键点。第一IFS禁止行内字段分割保证一行内容完整进入host变量不会被空格切开。第二|| [ -n $host ]处理最后一行没有换行符的情况避免最后一个主机被漏掉这是一个非常隐蔽的问题。第三用case匹配空行和#开头的注释行让主机列表文件可以直接带注释方便维护。-o BatchModeyes让 ssh 在无法交互时直接失败而不是挂住配合ConnectTimeout5能避免批量执行卡死。5. 生产环境跑这279个脚本5类避坑与排查记录把脚本从“能跑”变成“敢在凌晨三点让它自己跑”要过的坑比想象中多。下面这几类是我在多个环境里反复踩过的按出现频率从高到低排。5.1 现象脚本报“No such file or directory”但文件明明在这是 Windows 编辑脚本后最常见的翻车现场。你从 Windows 上传到 Linux脚本第一行是#!/usr/bin/env bash执行时却报No such file or directory或者提示/usr/bin/env bash^M。原因很简单文件是 CRLF 换行bash 解释器把回车符当成了命令或路径的一部分。解决方法是把所有脚本批量去掉\r# 批量把 CRLF 转成 LF find . -name *.sh -exec sed -i s/\r$// {} \; # 验证是否还有残留回车 cat -A bin/disk_check.sh | grep -n \^M || echo 没有残留 ^M绝大多数脚本集合下载后是压缩包不会强制转行。如果你在 Windows 上用编辑器改过脚本改完一定记得转回 LF。sed -i s/\r$//只去掉行尾回车不影响文件内容里的其他字符。cat -A是验证用的重要工具^M就是回车符的显示形态。5.2 现象中文输出乱码脚本里写的中文注释全变成“锟斤拷”某些脚本里带中文提示或日志说明运行环境语言环境不一样就会出现乱码。原因不是脚本本身坏了而是终端或机器的 locale 与脚本编码不匹配。解决方向有两个。一是统一把脚本编码设成 UTF-8二是运行脚本前导出语言环境# 在 /etc/profile.d/ 或 ~/.bashrc 里固定语言环境 export LC_ALLC.UTF-8 export LANGC.UTF-8注意不要把LC_ALL随便设成en_US.UTF-8因为服务器上不一定装了对应的 locale 包硬设反而会在某些命令里报错。C.UTF-8几乎每个发行版都有。你接手脚本库时可以先跑file 脚本名看编码如果是ISO-8859或GBK再考虑要不要转换。5.3 现象脚本依赖的命令本机没有跑一半就退出279个脚本里会有不少依赖外部命令最典型的是mysql、jq、bc、getopt。内网机器不一定允许随便装包。我见过有人在生产机器上因为没有jq而临时把 JSON 解析脚本改成grep sed这种做法短期可行但不好维护。更好的做法是先做依赖检查和降级方案# 依赖命令缺失时的优雅退出 if ! command -v jq /dev/null 21; then echo [WARN] jq 未安装跳过 JSON 解析功能 2 exit 3 fi这类脚本最关键的是“提前退出”而不是“跑到一半崩掉”。退出码用3这类业务码而不是127的 command not found方便上层平台区分原因。如果你确实要跑一个必须依赖某命令的脚本那就老老实实装依赖不要用 sed 硬解析 JSON那会让后续维护成本失控。5.4 现象脚本里有 rm 删除不知道会删到哪脚本合集里肯定有一批带rm -rf或find ... -delete的清理脚本。这类脚本风险最高。不要以为作者写对了就不会出事路径拼错一个字符就可能是灾难。我的处理习惯是拿到脚本后先做一次删除动作审计再决定要不要上生产。# 先列出脚本里所有删除动作只读审计 grep -nE rm(-rf)?\s|find\s.*-delete bin/*.sh这一步不执行删除只是把风险点列出来。看到rm -rf时先确认它的目标路径是否由固定值或参数控制再看有没有前置的目录存在性判断。比如rm -rf $LOG_DIR/*和rm -rf $LOG_DIR完全是两码事前者删文件后者连目录一起删。脚本里如果出现绝对路径写死的删除并且没有参数保护我一般会改成相对路径加变量甚至直接停用。5.5 现象定时任务里脚本不输出退出码为0但什么都没干脚本手动跑正常放进 crontab 之后要么不执行要么执行了但日志找不到。最常见的两个原因一个是 cron 环境里的 PATH 和你交互终端里的 PATH 不一样脚本里用的命令找不到另一个是脚本输出重定向到某个不存在的目录cron 直接丢弃输出。# 在脚本顶部固定 PATH 和关键变量 export PATH/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin export TZUTC把 PATH 写死在脚本顶部而不是依赖用户环境是让脚本能在 cron 里稳定运行的底线操作。除了 PATH还要检查脚本里有没有用相对路径cron 的工作目录默认是用户家目录相对路径很容易失效。日志文件尽量用绝对路径并确保脚本运行时日志目录已经存在。6. 把279个脚本变成自己的养成“注释即文档、模板即复用”的小习惯脚本库跑通只是第一步真正让这279个脚本产生长期价值的方式是把它拆成自己能复用的模板而不是让一个庞大的合集一直占据磁盘。我现在的维护方式很简单所有脚本只要经过改造就把用法注释写成一两行并保持统一的参数风格。6.1 给每个脚本加 usage 函数替代散落的 echo我习惯在每个脚本开头加一个usage()函数把接受的参数列出来再在主逻辑里判断$#是否足够。这种做法的收益很直接三个月后你回来看脚本不用靠回忆别人接手时也不用打开正文读一遍。#!/usr/bin/env bash set -Eeuo pipefail usage() { cat EOF 用法: $(basename $0) 日志目录 [保留天数] 示例: $(basename $0) /var/log/nginx 14 EOF exit 2 } [ $# -lt 1 ] usage LOG_DIR$1 KEEP_DAYS${2:-7}6.2 从279个脚本里抽3个模板而不是背诵所有脚本把这个合集坚持用了三个月之后我最大的心得是不要试图记住每个脚本而是总结出三个自己最常用的模板例如“参数校验加退出码加输出规范”的巡检类模板、“环境变量加默认值加日志切割”的清理类模板、“while read加跳过注释加超时控制”的批量操作类模板。遇到新需求时先在模板上改而不是翻合集从头找。6.3 验证脚本回归改一行之后跑一次它的反例每次改动脚本之后我习惯跑它最容易出错的反例比如不传参数、传空目录、把阈值设成0。验证一遍不是为了说服自己它能跑而是确认失败路径是可预期的。这个习惯救过我一次日志切割脚本改完保留天数后当天晚上定时任务跑完没误删就是因为提前测了“目录不存在”和“文件为空”这两种情况。一套脚本敢用多久不取决于它当时写了多好而取决于你改它的时候有多稳。希望帮到你。本文还有配套的精品资源点击获取
返回列表