ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

Linux运维必备:常用Shell脚本合集与避坑指南

Linux运维必备:常用Shell脚本合集与避坑指南 简介这份资源是面向Linux运维工程师与Shell脚本学习者的实用脚本合集聚焦日常运维场景的自动化落地帮助读者减少重复手工操作、提升排障与巡检效率。压缩包内共1个PDF文件约100KB内容以脚本示例与命令讲解为主便于随身查阅与对照练习。资料覆盖日志过滤与错误统计、服务健康检查、ping批量测试、旧文件清理、备份压缩、循环多文件操作、scp远程传输、用户home目录校验、日志实时监控、自动化建用户、进程检查与kill、服务器初始化配置等模块并配有可直接参考的代码片段与注释说明。目前已有1165人学习下载适合初具Shell基础、希望把零散命令沉淀为可复用脚本的运维人员也可作为日常巡检与故障排查的思路参考。1. 从一份 shell 脚本合集说起运维日常到底在自动化什么凌晨两点被告警叫醒登机器一看是某个日志目录把磁盘写满了。手动du一圈、删文件、重启服务十分钟搞定但这种事一个月来八回谁受得了。很多做服务器运维、机房运维的同行手头都会攒一份自己的 shell 脚本合集标题里那种「Linux运维必备工作常用shell脚本」的 PDF本质就是把这类重复劳动沉淀成可复用的命令组合。它解决的不是什么高深问题而是把「每天都要敲一遍」的动作变成「跑一个脚本就完事」。适合谁刚入行的桌面运维、网络运维以及被 linux常用命令大全背得滚瓜烂熟却还是天天加班的初中级工程师。这篇不聊虚的就按一份脚本合集该有的样子把常用脚本怎么写、参数怎么设、shell中常见坑在哪一条条拆开讲清楚。2. 写之前先想清楚哪些运维场景值得做成脚本不是所有命令都值得封装成脚本。我见过有人把ls都包一层结果自己都记不住脚本名。判断标准很简单这个操作一周内重复超过三次且步骤固定、输入输出明确就值得写。下面按场景分类把最常被收进脚本合集的几类挑出来。2.1 磁盘与日志清理最高频也最容易翻车的场景磁盘告警是运维第一大日常。核心逻辑就三步找到大文件、判断能不能删、删完确认。但直接rm -rf是血泪经验的来源脚本里必须加保护。#!/bin/bash # 清理指定目录下超过 N 天的日志文件 # 用法: ./clean_logs.sh /var/log/app 7 LOG_DIR$1 KEEP_DAYS$2 # 参数校验防止手滑传空值把根目录扫了 if [ -z $LOG_DIR ] || [ -z $KEEP_DAYS ]; then echo 用法: $0 日志目录 保留天数 exit 1 fi if [ ! -d $LOG_DIR ]; then echo 目录不存在: $LOG_DIR exit 1 fi # 先 dry-run 打印确认无误再真正删除 echo 以下文件将被删除: find $LOG_DIR -type f -name *.log -mtime $KEEP_DAYS -print read -p 确认删除? (y/n): confirm if [ $confirm y ]; then find $LOG_DIR -type f -name *.log -mtime $KEEP_DAYS -delete echo 清理完成 else echo 已取消 fi逻辑说明find的-mtime N表示修改时间在 N 天以前-print先列出来给人看这是后悔药。参数说明第一个参数是目录绝对路径第二个是保留天数建议日志至少留 7 天。注意-delete和-print不要写在同一条 find 里同时执行先看后删。2.2 服务健康检查与自动拉起别让进程悄悄死掉服务挂了但没人知道是运维最被动的事。一个轻量健康检查脚本配合 crontab 每分钟跑一次比很多重型监控上手快。#!/bin/bash # 检查进程是否存在不存在则拉起并记录 PROCESS_NAMEnginx START_CMD/usr/sbin/nginx LOG_FILE/var/log/health_check.log # pgrep 比 ps|grep 更干净不会匹配到 grep 自身 if ! pgrep -x $PROCESS_NAME /dev/null; then echo $(date %F %T) $PROCESS_NAME 未运行尝试拉起 $LOG_FILE $START_CMD sleep 2 if pgrep -x $PROCESS_NAME /dev/null; then echo $(date %F %T) 拉起成功 $LOG_FILE else echo $(date %F %T) 拉起失败需人工介入 $LOG_FILE fi fi逻辑说明pgrep -x精确匹配进程名避免误判。参数说明PROCESS_NAME要和实际进程名一致用ps -ef确认。注意拉起后要 sleep 再复查否则可能进程还没起来就判定失败。2.3 批量文件重命名与归档linux用shell重命名文件的稳妥写法批量改名是 shell脚本for循环 的经典练习场。比如把一批.txt改成带日期的名字。#!/bin/bash # 给目录下所有 .txt 文件加日期前缀 TARGET_DIR$1 DATE_TAG$(date %Y%m%d) for file in $TARGET_DIR/*.txt; do # 防止目录为空时 file 变成字面量 [ -e $file ] || continue base$(basename $file) mv $file $TARGET_DIR/${DATE_TAG}_${base} done逻辑说明for循环遍历通配符结果[ -e $file ] || continue是空目录保护不加这行目录为空时会报错。参数说明传入目标目录即可。注意文件名含空格时变量必须加双引号这是 shell中常见坑 里排前三的。3. 参数、循环与判断把脚本写稳的三个基本功脚本能跑和跑得稳是两回事。翻车往往不在逻辑而在参数没校验、循环边界没处理、判断条件写反。这一章把这三块讲透。3.1 参数处理shift 命令和默认值怎么配合shift是处理不定参数的利器但很多人用不明白。它的作用是把位置参数左移$2变成$1常用于逐个消费参数。#!/bin/bash # 演示 shift 逐个处理参数 while [ $# -gt 0 ]; do case $1 in -d|--dir) DIR$2 shift 2 # 消费掉 -d 和它的值 ;; -n|--days) DAYS$2 shift 2 ;; *) echo 未知参数: $1 exit 1 ;; esac done # 给默认值避免空变量 DIR${DIR:-/var/log} DAYS${DAYS:-7} echo 目录$DIR 天数$DAYS逻辑说明case匹配参数名shift 2一次消费两个位置选项和值。参数说明${VAR:-默认值}是给变量兜底的写法比if [ -z ]更简洁。注意shift 2前要确认$2存在否则会移过头。3.2 for 循环的边界什么时候用通配符什么时候用列表shell脚本for循环 有两种常见形态选错了就是坑。写法适用场景注意点for f in *.log遍历目录下匹配文件无匹配时 f 为字面量需[ -e ]保护for i in $(seq 1 10)固定次数循环命令替换会分词文件名含空格会出错for line in $(cat file)逐行读文件强烈不推荐空格和换行都会出问题while read line逐行读文件推荐配合IFS保留行首尾空格读文件逐行处理正确姿势是while read#!/bin/bash # 逐行读取服务器列表并执行操作 while IFS read -r host; do # 跳过空行和注释行 [ -z $host ] continue case $host in \#*) continue ;; esac echo 处理主机: $host # ssh $host uptime # 实际执行时打开 done server_list.txt逻辑说明IFS防止行首尾空格被吃掉-r防止反斜杠被转义。参数说明server_list.txt每行一个主机名。注意while read里如果调用了会读 stdin 的命令要用 /dev/null隔开否则循环会被吃掉。3.3 判断条件文件测试和字符串比较别写混[ ]里字符串比较用数值比较用-eq文件测试用-f -d -e。写混了不报错但结果错最坑。#!/bin/bash FILE/etc/passwd # 文件存在且是普通文件 if [ -f $FILE ]; then echo $FILE 是普通文件 fi # 数值比较 COUNT$(wc -l $FILE) if [ $COUNT -gt 10 ]; then echo 行数超过10 fi # 字符串比较注意两边加引号 NAME if [ -z $NAME ]; then echo NAME 为空 fi逻辑说明-f判断普通文件-d判断目录-z判断字符串为空。参数说明数值比较用-gt -lt -eq字符串用 !。注意[ $COUNT -gt 10 ]里变量加引号防止 COUNT 为空时报语法错误。4. 避坑与排查shell 脚本最常见的五类翻车脚本写完跑一次成功不代表没问题换个环境、换个输入就崩。下面五条是我踩过或见别人踩过的按「现象 → 原因 → 解决」写。4.1 现象脚本手动跑正常crontab 里不执行原因crontab 的环境变量和登录 shell 不同PATH 极简很多命令找不到另外工作目录也不是脚本所在目录。解决脚本里用绝对路径调用命令或在开头显式设置 PATH涉及相对路径的文件全部改成绝对路径。可以在 crontab 里重定向输出 /tmp/cron.log 21看报错。4.2 现象变量明明有值判断却走了空分支原因变量赋值时带了空格比如NAME abcshell 会把NAME当命令执行赋值失败。解决赋值等号两边不能有空格写成NAMEabc。用set -u让未定义变量直接报错早发现早治疗。4.3 现象rm 删除了预期外的文件原因变量为空时rm -rf $DIR/*变成rm -rf /*这是最惨的翻车。解决删除前判断变量非空[ -n $DIR ] || exit 1或者用set -u。更稳的做法是先echo出要删的路径确认后再执行。4.4 现象文件名带空格循环处理时被拆成多个原因for f in $(ls)或未加引号的变量展开shell 按空格分词。解决用for f in $DIR/*配合引号或while IFS read -r。所有变量引用加双引号这是 shell中常见坑 里最该养成的习惯。4.5 现象脚本执行到一半退出没有任何提示原因某条命令返回非零配合set -e时脚本直接终止但没打印是哪条。解决用set -e的同时加trap echo 错误发生在第 $LINENO 行 ERR定位到具体行。或者关键命令后手动判断|| { echo 失败; exit 1; }。5. 让脚本合集真正好用版本管理、日志与自检一份脚本攒到几十个就会遇到「这个脚本是干嘛的」「改了哪版」的问题。最后一章聊几个让合集长期可用的技巧。5.1 给每个脚本加统一头部注释和自检脚本头部写清用途、用法、作者、日期配合--help自检别人包括三个月后的自己才看得懂。#!/bin/bash # 脚本名: clean_logs.sh # 用途: 清理指定目录下超过N天的日志 # 用法: ./clean_logs.sh 目录 天数 # 示例: ./clean_logs.sh /var/log/app 7 usage() { sed -n 2,5p $0 # 打印头部注释作为帮助 exit 0 } [ $1 -h ] || [ $1 --help ] usage逻辑说明sed -n 2,5p $0直接读脚本自身第 2 到 5 行当帮助信息改注释即改帮助不用维护两份。参数说明$0是脚本自身路径。注意sed行号要和实际注释行对应。5.2 用日志和退出码让脚本可观测脚本不能是黑匣子。关键步骤写日志退出码规范配合监控才能形成闭环。退出码含义使用场景0成功正常结束1通用错误参数错误、目录不存在2用法错误缺少必要参数3依赖缺失命令未安装#!/bin/bash LOG_FILE/var/log/my_script.log log() { echo $(date %F %T) [$1] $2 $LOG_FILE } log INFO 脚本开始 if ! command -v rsync /dev/null; then log ERROR rsync 未安装 exit 3 fi log INFO 脚本结束逻辑说明command -v检查命令是否存在比which更可移植。参数说明日志级别自定义建议至少 INFO 和 ERROR 两级。注意日志文件要配合 logrotate否则自己也会撑爆磁盘。5.3 版本管理脚本也要进 git别再用script_v2_final_真的最终版.sh这种命名了。建一个 git 仓库按功能分目录提交信息写清楚改了什么。这样出问题能回滚多人协作也不打架。我自己的习惯是每个脚本配一个同名.md说明记录参数变更和已知问题比写在脚本注释里更灵活。脚本合集的价值不在数量而在每个都经过真实场景验证、有保护、有日志、能回滚。从今天起把手上重复三次以上的操作挑一个写成脚本加上参数校验和 dry-run跑一周看看省了多少时间。希望帮到你。本文还有配套的精品资源点击获取
返回列表