资讯动态

LinuxShell脚本编程实战指南

发布时间:2026/10/15 4:02:09 来源:尧图企业网站定制
Linux Shell 脚本编程实战指南Shell 脚本是运维工程师的吃饭手艺也是 CSDN Linux 板块流量最大的话题。前面的《Linux报错踩坑》讲了命令排障这篇系统讲脚本编程变量、条件、循环、函数、文本处理三剑客、实战脚本日志清理/备份/监控、调试技巧。一、Shell 是什么1.1 定位Shell 是 Linux 的命令解释器也是脚本语言——把命令组织成可复用的程序。常见 ShellShell特点bashLinux 默认最常用sh最老POSIX 标准zsh交互体验好macOS 默认fish对用户友好语法不同本文以 bash 为准服务器默认。1.2 第一个脚本#!/bin/bash# 注释脚本第一行声明解释器echoHello, Shell!echo当前时间:$(date)chmodx hello.sh# 加执行权限./hello.sh# 执行bashhello.sh# 或直接 bash 执行二、变量2.1 定义与使用# 定义等号两边不能有空格name张三age25path$(pwd)# 命令替换num$((12))# 算术运算# 使用变量名前加 $echo姓名:$nameecho年龄:${age}岁# {} 隔离边界echo路径:$path2.2 特殊变量变量含义$0脚本名$1 $2 …位置参数$#参数个数$ / $*所有参数$?上一条命令退出码0成功$$当前进程 PID$HOME / $PATH环境变量echo脚本名:$0echo第一个参数:$1echo参数个数:$#echo所有参数:$2.3 字符串处理strhello world# 长度echo${#str}# 11# 截取echo${str:0:5}# hello# 替换echo${str/world/shell}# hello shell只替换第一个# 默认值echo${undefined:-默认值}# 变量为空时用默认值echo${undefined:?变量未设置}# 为空则报错退出三、条件判断3.1 if 语法if[条件];then# 成立elif[条件];then# 分支else# 都不成立fi3.2 数值/字符串/文件判断# 数值比较注意-eq 不是 [$age-gt18]# -gt -ge -lt -le -eq -ne !# 字符串比较[$name张三]# 相等 两边加引号防空格[-z$name]# 是否为空[-n$name]# 是否非空# 文件判断[-f$file]# 是普通文件[-d$dir]# 是目录[-x$file]# 可执行[-r$file]# 可读[-e$path]# 存在[-s$file]# 非空文件# 组合[-f$file]echo存在# 且[-d$dir]||echo不存在# 或3.3 实战示例#!/bin/bash# 判断参数并执行if[$#-ne1];thenecho用法:$0目录exit1fiif[!-d$1];thenecho错误:$1不是有效目录exit1fiecho目录$1存在3.4 case 分支case$1instart)echo启动服务;;stop)echo停止服务;;restart)echo重启服务;;*)echo用法:$0{start|stop|restart}exit1;;esac四、循环4.1 for 循环# 遍历列表foripin192.168.1.1192.168.1.2192.168.1.3;doechoPing$ipping-c1$ip/dev/nullecho 通||echo 不通done# 遍历数字foriin$(seq110);doecho第$i次done# C 风格for((i0;i5;i));doechoi $idone# 遍历文件forfilein/var/log/*.log;doecho处理$filedone4.2 while 循环# 读文件每一行whileIFSread-rline;doecho行:$linedone/etc/hosts# 无限循环 条件退出count0whiletrue;docount$((count1))echo第$count次if[$count-ge5];thenbreakfidone五、函数#!/bin/bash# 定义函数log(){locallevel$1# local局部变量localmsg$2echo[$(date%F %T)] [$level]$msg}check_port(){localport$1ifss-tln|grep-q:$port;thenlog INFO端口$port在监听return0elselog ERROR端口$port未监听return1fi}# 调用log INFO脚本启动check_port8080if[$?-ne0];thenlog WARN8080 未启动跳过fi注意函数内local声明局部变量避免污染全局return返回状态码0-255函数必须先定义后调用。六、文本处理三剑客核心6.1 grep查找# 基础greperrorapp.log# 匹配行grep-ierrorapp.log# 忽略大小写grep-vdebugapp.log# 反选排除grep-cerrorapp.log# 计数grep-nerrorapp.log# 带行号grep-rerror/app/logs/# 递归目录grep-Eerror|failapp.log# 扩展正则或# 实战统计某段时间的错误grep2026-10-14app.log|grepERROR|wc-l6.2 sed替换/编辑# 替换打印到标准输出不改文件seds/old/new/file# 每行第一个seds/old/new/gfile# 全部替换gsed-is/old/new/gfile# -i 直接改文件# 删除sed/^#/dconfig.conf# 删注释行输出sed-i/^#/dconfig.conf# 删注释行改文件# 实战把配置文件里的端口改成 8081sed-is/port8080/port8081/application.conf6.3 awk分析/统计# 按列处理默认空格分割awk{print $1, $3}file# 打印第 1、3 列awk-F:{print $1}/etc/passwd# 按 : 分割取用户名# 过滤 统计awk$3 100 {print $1}data.txt# 第3列100 的行# 实战统计日志里的接口调用次数awk{print $7}access.log|sort|uniq-c|sort-rn|head-10# 解释取第7列URL→ 排序 → 去重计数 → 按次数倒序 → 前10三剑客组合实战分析访问日志# 1. 访问量最高的 IP Top10awk{print $1}access.log|sort|uniq-c|sort-rn|head-10# 2. 404 错误统计awk$9 404 {print $7}access.log|sort|uniq-c|sort-rn|head# 3. 每小时请求数awk{print substr($4, 14, 2)}access.log|sort|uniq-c七、实战脚本7.1 日志清理脚本防磁盘满#!/bin/bash# 清理超过 7 天的日志LOG_DIR/var/log/myappKEEP_DAYS7echo开始清理$LOG_DIR下$KEEP_DAYS天前的日志# find 删除find$LOG_DIR-name*.log-typef-mtime$KEEP_DAYS-delete# 压缩更稳的方案# find $LOG_DIR -name *.log -mtime $KEEP_DAYS -exec gzip {} \;# 计算释放空间size_before$(du-sh$LOG_DIR|cut-f1)echo当前占用:$size_before7.2 数据库自动备份#!/bin/bash# MySQL 每日备份保留 7 天BACKUP_DIR/backup/mysqlDB_USERrootDB_PASS123456DATE$(date%Y%m%d)mkdir-p$BACKUP_DIR# 备份所有库mysqldump -u$DB_USER-p$DB_PASS--all-databases\|gzip$BACKUP_DIR/all_$DATE.sql.gz# 删除 7 天前备份find$BACKUP_DIR-name*.sql.gz-mtime7-deleteecho备份完成:$BACKUP_DIR/all_$DATE.sql.gz7.3 服务健康检查#!/bin/bash# 检查服务端口挂了自动重启SERVICEmyappPORT8080if!ss-tln|grep-q:$PORT;thenecho[$(date)]$SERVICE挂了正在重启/var/log/watchdog.log systemctl restart$SERVICE||(cd /appnohup./myapp)elseecho[$(date)]$SERVICE正常fi八、调试与技巧8.1 调试三招bash-nscript.sh# 只检查语法bash-xscript.sh# 打印每条命令最常用bash-vscript.sh# 打印原始输入# 脚本里局部调试set-x# 开启跟踪# ... 可疑代码 ...setx# 关闭跟踪8.2 安全规范# 脚本开头加重要set-e# 命令失败立即退出防止带错继续跑set-u# 变量未定义报错set-opipefail# 管道中任一命令失败整体失败# 完整写法#!/bin/bashset-euopipefail8.3 常见坑现象原因解决变量赋值报错等号两边有空格namexx 不留空格文件名带空格失效没加引号“$file” 加引号数字比较报错用了 不是 -gt[ $a -gt $b ]set -e 后莫名退出命令返回非0中文乱码编码export LANGzh_CN.UTF-8crontab 里跑不起来环境变量不全脚本内 export PATH本章小结Shell 脚本的核心能力变量 条件 循环 函数 文本三剑客。日常 80% 的需求清理、备份、监控、部署都是这几个要素的组合。写脚本的两个好习惯开头set -euo pipefail、所有变量加引号。多看三剑客组合分析日志的例子运维效率翻倍。下一篇讲 Netty——Java 高并发网络编程的王者。全文完

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑