当前位置: 首页 > article >正文

Shell 脚本:别让你的自动化变成“自爆化”

太长不看版老鸟脚本头#!/bin/bash写死别用#!/bin/sh坑太多。调试bash -x script.sh能看到每一行执行过程。变量引用永远用双引号包起来$var否则空格和通配符会让你怀疑人生。返回值$?是上一条命令的退出码0表示成功。安全set -euo pipefail是脚本的“保命三件套”。我见过一个脚本备份数据库前忘了检查磁盘空间结果把系统盘写爆了。自动化不是写出来就完事要考虑到每一步可能失败。一、你为什么要学 Shell 脚本运维、开发、DevOps只要你和 Linux 打交道Shell 脚本就是你的瑞士军刀。它能帮你每天自动备份日志、数据库批量修改 100 台服务器的配置监控系统资源出问题自动报警把繁琐的手动操作变成一行命令读完这篇你会写出健壮的、可维护的、不会半夜炸醒你的脚本。前置条件会敲基本的 Linux 命令ls、grep、awk。我在 Ubuntu 22.04 和 CentOS 7 上都测过macOS 的 bash 版本旧一点3.2但大部分语法通用。二、脚本的基本骨架直接复制就能用我写脚本时开头一定是这个模板#!/bin/bash set -euo pipefail # 脚本所在目录绝对路径 SCRIPT_DIR$(cd $(dirname ${BASH_SOURCE[0]}) pwd) # 日志函数 log() { echo [$(date %Y-%m-%d %H:%M:%S)] $* } # 错误退出 die() { echo ERROR: $* 2 exit 1 } # 你的逻辑从这里开始 log 脚本开始运行解释一下set -euo pipefail这三个参数我强烈建议每个脚本都加上参数作用不用的后果-e任何命令失败返回值非0立即退出某行报错还继续跑越错越离谱-u引用未定义变量时报错变量拼写错误变成空删错文件-o pipefail管道中只要有一个命令失败整个管道就算失败cat file | grep x即使cat失败grep也返回0你以为成功彩蛋set -x可以在调试时打印每条命令。上线时记得关掉否则日志刷屏。三、变量引用时别偷懒3.1 定义和使用nameTony # 等号两边不能有空格 echo Hello, $name # 输出 Hello, Tony echo Hello, ${name} # 花括号可选但遇到拼接时有用 echo Hello, $name! # 也能工作但 ${name}! 更清晰我踩过的坑$name如果包含空格不加大括号会分裂成多个参数。所以一律用双引号包起来filemy important doc.txt rm $file # 报错rm 收到了 my important doc.txt 三个参数 rm $file # 正确删除一个文件3.2 默认值和替换# 如果变量没定义用默认值 echo ${LOG_DIR:-/var/log} # LOG_DIR 未定义输出 /var/log # 如果变量没定义报错退出 echo ${REQUIRED_VAR:?请设置该变量}四、条件判断if 的写法巨坑[ ]和[[ ]]有什么区别我用[[ ]]因为它支持正则、不会因为变量为空报错。if [[ -f /etc/passwd ]]; then echo 文件存在 fi if [[ $USER root ]]; then echo 你是老大 else echo 你只是个普通人 fi常用文件测试操作符操作符含义-f存在且是普通文件-d存在且是目录-e存在文件或目录-r/-w/-x可读/可写/可执行-s文件非空数字比较别用那是字符串比较if [[ $count -gt 10 ]]; then # -gt, -lt, -eq, -ge, -le echo 超过10 fi五、循环处理批量任务5.1 for 循环# 遍历文件 for file in /var/log/*.log; do echo 处理 $file gzip $file done # C 风格 for ((i1; i10; i)); do echo 第 $i 次 done5.2 while 循环读文件while IFS read -r line; do echo 行内容: $line done data.txtIFS保留行首尾空格-r防止转义。这是标准写法记下来就行。六、函数别把脚本写成两千行# 定义函数 backup_file() { local src$1 local dst$2 cp -p $src $dst || return 1 echo 备份完成: $dst } # 调用 backup_file /etc/nginx/nginx.conf /backup/nginx.conf要点用local声明局部变量避免污染全局。$1、$2是传给函数的参数不是脚本参数。函数返回值用return0~255调用后检查$?。七、错误处理脚本的“安全气囊”7.1 检查命令是否成功if ! mkdir /backup/mydata; then echo 创建目录失败退出 exit 1 fi或者直接用||短路mkdir /backup/mydata || { echo 失败; exit 1; }7.2 捕获退出信号trap这个技巧救过我很多次脚本被中断时清理临时文件。temp_file$(mktemp) # 无论正常退出还是 CtrlC都删除临时文件 trap rm -f $temp_file EXITtrap可以捕获的信号INTCtrlC、TERM、EXIT脚本结束。八、实战例子一个备份脚本把上面知识点串起来。假设我要备份 MySQL 数据库并保留最近 7 天。#!/bin/bash set -euo pipefail # 配置 BACKUP_DIR/backup/mysql DB_NAMEmyapp DB_USERroot DB_PASSyourpassword # 生产环境用 .my.cnf别明文写 RETENTION_DAYS7 # 创建备份目录如果不存在 mkdir -p $BACKUP_DIR # 生成备份文件名 DATE$(date %Y%m%d_%H%M%S) BACKUP_FILE$BACKUP_DIR/${DB_NAME}_${DATE}.sql.gz # 执行备份 mysqldump -u $DB_USER -p$DB_PASS $DB_NAME | gzip $BACKUP_FILE # 检查备份是否成功 if [[ $? -eq 0 -s $BACKUP_FILE ]]; then echo 备份成功: $BACKUP_FILE else echo 备份失败 2 exit 1 fi # 删除超过7天的备份 find $BACKUP_DIR -name ${DB_NAME}_*.sql.gz -mtime $RETENTION_DAYS -delete echo 完成预期输出成功时备份成功: /backup/mysql/myapp_20250125_030001.sql.gz 完成九、常见错误与解决方法错误 1./script.sh: Permission denied原因脚本没有执行权限。解决chmod x script.sh错误 2[: too many arguments原因[ $var value ]中$var是空值或包含多个单词。解决用双引号[ $var value ]或改用[[ ]]。错误 3command not found但命令明明存在原因脚本的环境变量PATH可能不包含/usr/local/bin等。解决在脚本里写绝对路径或开头加export PATH/usr/local/bin:$PATH。错误 4循环读取文件时最后一行丢失原因用while read line但文件最后一行没有换行符。解决用while read line || [[ -n $line ]]。十、几个能让你效率翻倍的彩蛋$()vs 反引号用$(cmd)不要用 cmd 因为前者支持嵌套。${var#pattern}从开头删除最短匹配。filea.b.c.txt${file%.*}得a.b.c${file##*.}得txt。数组arr(a b c)echo ${arr[]}所有元素echo ${#arr[]}个数。read -p交互输入read -p 输入你的名字: name。select菜单不用写一堆 echo直接用select opt in 启动 停止 重启; do case $opt in 启动) echo 启动服务; break ;; 停止) echo 停止服务; break ;; 重启) echo 重启服务; break ;; esac done十一、验证你的脚本水平自己动手写一个脚本要求接受一个参数目录路径。检查目录是否存在不存在则报错退出。找出该目录下所有.log文件统计每个文件的行数输出格式文件名: 行数。将结果保存到report.txt。参考实现先别看写完再对#!/bin/bash set -euo pipefail target_dir${1:-} if [[ -z $target_dir ]]; then echo 用法: $0 目录路径 2 exit 1 fi if [[ ! -d $target_dir ]]; then echo 错误: $target_dir 不是目录 2 exit 1 fi reportreport.txt $report # 清空文件 for logfile in $target_dir/*.log; do if [[ -f $logfile ]]; then lines$(wc -l $logfile) echo $(basename $logfile): $lines 行 $report fi done echo 报告已生成: $reportShell 脚本看着简单但想写得稳、不出幺蛾子得花心思。我写了十年脚本至今还在踩坑。你有什么独门技巧或者惨痛教训欢迎留言分享让大伙儿少走弯路。如果这篇对你有帮助点个赞让更多人看到。

相关文章:

Shell 脚本:别让你的自动化变成“自爆化”

太长不看版(老鸟)脚本头:#!/bin/bash 写死,别用 #!/bin/sh(坑太多)。调试:bash -x script.sh 能看到每一行执行过程。变量引用:永远用双引号包起来 "$var",否则…...

macOS Monterey安装OpenClaw避坑指南:千问3.5-9B适配

macOS Monterey安装OpenClaw避坑指南:千问3.5-9B适配 1. 为什么选择OpenClaw千问3.5-9B组合 去年换装M1 Max芯片的MacBook Pro后,我一直在寻找能充分发挥ARM架构性能的本地AI方案。直到遇见OpenClaw这个开源的自动化智能体框架,配合千问3.5…...

WebStorm高效开发Vue3+TypeScript项目:配置与实战技巧

1. WebStorm与Vue3TypeScript开发环境搭建 WebStorm作为JetBrains旗下的前端开发利器,对Vue3和TypeScript的支持堪称完美。最新版本甚至内置了Volar语言服务,让类型推断和代码补全更加精准。先说说我的踩坑经历:第一次用WebStorm创建Vue3项目…...

DAMO-YOLO TinyNAS模型评估全攻略:mAP/PR曲线

DAMO-YOLO TinyNAS模型评估全攻略:mAP/PR曲线 1. 为什么模型评估比训练更重要 刚跑通DAMO-YOLO TinyNAS的训练流程时,很多人会直接跳到部署环节,觉得“能出结果就行”。但实际项目中,我见过太多团队在交付前才发现模型在真实场景…...

当AI学会“动手”,架构师如何为它“刹车”?

当AI Agent开始自主执行文件读写、邮件收发、系统操作,你交给它的权限,到底是“效率工具”还是“失控炸弹”? 2026年开年,OpenClaw引爆了AI Agent领域——大模型从“会聊天”迈入“能行动”的时代。Meta安全专家的一条指令&#x…...

【网络安全】从零开始:15种常见网络攻击类型及防御措施全解析,小白必备!建议收藏学习!

【网络安全】从零开始:15种常见网络攻击类型及防御措施全解析,小白必备!建议收藏学习! 随着攻击者效率和复杂性的提高,网络犯罪每年都在急剧增加。[网络攻击]的发生有多种不同的原因和多种不同的方式。但是&#xff0c…...

IMX6ULL开发板实战:NFS挂载报错No route to host的5种修复方法

IMX6ULL开发板NFS挂载故障排查指南:从"No route to host"到稳定连接 嵌入式开发过程中,NFS挂载几乎是每位开发者都会遇到的基础操作。但当开发板突然提示"No route to host"时,那种调试过程中的挫败感我深有体会——明明…...

InfixPDFEditor:解决PDF文本编辑与添加水印的实用指南

在日常办公中,你是否收到过一份PDF合同,发现里面有一个错别字却无法修改;或者需要给几十页的PDF文件批量加上公司logo水印,却只能一页页截图;又或者需要对比两个版本的PDF文档差异,肉眼逐行比对眼睛都快看花…...

从“词元”到“符元”:Token中文定名的再思考——以概念精确性与长期稳定性为视角

近日,全国科学技术名词审定委员会发布公告,推荐将人工智能领域中的“Token”译为“词元”,并面向社会试用。随后,《人民日报》发文《专家解读token中文名为何定为“词元”》,对这一命名从专业角度进行了系统阐释。文中…...

云原生应用开发最佳实践:构建现代化的云原生系统

云原生应用开发最佳实践:构建现代化的云原生系统 前言 作为一个在数据深渊里捞了十几年 Bug 的女码农,我深知云原生应用开发在现代企业中的重要性。随着云技术的快速发展,传统的应用开发方式已经难以满足需求。今天,我就来聊聊云原…...

WinISO:解决光盘镜像编辑与制作的三大实际问题

在日常工作中,你是否遇到过这样的场景:下载了一个 ISO 镜像文件,想往里面添加几个补丁或删除一个无用文件,却只能解压后再重新打包;或者你有一个旧版 Windows 安装盘,想替换其中的 install.wim 文件来制作集…...

SITS2026平台深度拆解:如何用1套配置实现92%业务场景零代码交付?(附Gartner验证的ROI测算模型)

第一章:SITS2026平台深度拆解:如何用1套配置实现92%业务场景零代码交付?(附Gartner验证的ROI测算模型) 2026奇点智能技术大会(https://ml-summit.org) SITS2026并非传统低代码平台的简单迭代,而是基于语义…...

AI驱动的知识管理平台构建全路径(从零到生产级上线的12个关键决策点)

第一章:AI原生软件研发知识管理平台的范式跃迁 2026奇点智能技术大会(https://ml-summit.org) 传统知识管理平台以文档为中心,依赖人工归档、关键词检索与静态权限控制,难以应对AI原生研发中高频迭代、多模态产出(如提示工程日志…...

ROS2 Humble下Cartographer纯定位不成功?别急,可能是你的.lua配置文件少了这行关键代码

ROS2 Humble下Cartographer纯定位失败的深度排查与解决方案 当你在RViz中看到地图显示正常,但激光雷达点云始终无法与地图正确匹配时,那种挫败感我深有体会。去年在部署仓库AGV项目时,我花了整整三天时间排查类似问题,最终发现是.…...

【仅限SITS2026参会者解封】:AI微服务弹性扩缩容决策引擎设计手册(含动态负载预测模型Python实现+K8s HPA自定义指标CRD YAML)

第一章:SITS2026分享:AI原生微服务架构设计 2026奇点智能技术大会(https://ml-summit.org) 在SITS2026现场,来自全球头部AI基础设施团队的实践者共同提出“AI原生微服务”范式——它并非传统微服务的简单迁移,而是围绕模型生命周…...

从稀疏重构到精准定位:l1-SVD算法的核心思想与工程实现

1. 稀疏信号重构与DOA估计的困境 想象你站在一个嘈杂的会议室里,试图通过几个麦克风确定说话人的方位。这就是DOA(波达方向)估计的典型场景。传统方法如MUSIC算法在理想环境下表现优异,但当信源间距过小或快拍数不足时&#xff0c…...

如何高效掌握DeepONet:5步快速上手非线性算子深度学习实战指南

如何高效掌握DeepONet:5步快速上手非线性算子深度学习实战指南 【免费下载链接】deeponet Learning nonlinear operators via DeepONet based on the universal approximation theorem of operators 项目地址: https://gitcode.com/gh_mirrors/de/deeponet D…...

数码管展示

文章目录文章目录1.数码管显示6个91.1 效果图展示1.2 代码2.数码管显示2个72.1 效果图展示2.2 代码3.数码管轮播显示6位3.1 效果图展示3.2 代码4.数码管轮播显示2位4.1 效果图展示4.2 代码5.数码管显示0-55.1 效果图展示6.思考题6.1如何显示数码管1-6轮播6.1.1 效果图展示6.1.2…...

如何在Switch上使用Xbox和PlayStation手柄?sys-con让您的第三方控制器焕发新生

如何在Switch上使用Xbox和PlayStation手柄?sys-con让您的第三方控制器焕发新生 【免费下载链接】sys-con Nintendo Switch sysmodule that allows support for third-party controllers 项目地址: https://gitcode.com/gh_mirrors/sy/sys-con 您是否曾想过&a…...

OpenClaw 太难装了?试试 LangTARS:一行命令部署 + WebUI 管理面板,还能接入 Dify/Coze/nn??孛

1. 什么是 Apache SeaTunnel? Apache SeaTunnel 是一个非常易于使用、高性能、支持实时流式和离线批处理的海量数据集成平台。它的目标是解决常见的数据集成问题,如数据源多样性、同步场景复杂性以及资源消耗高的问题。 核心特性 丰富的数据源支持&#…...

G-Helper终极指南:三步恢复ROG笔记本GameVisual色彩配置文件

G-Helper终极指南:三步恢复ROG笔记本GameVisual色彩配置文件 【免费下载链接】g-helper Lightweight, open-source control tool for ASUS laptops and ROG Ally. Manage performance modes, fans, GPU, battery, and RGB lighting across Zephyrus, Flow, TUF, Str…...

【AI原生软件性能基准测试黄金标准】:20年实战总结的7大不可绕过陷阱与5步精准压测法

第一章:AI原生软件性能基准测试的范式革命 2026奇点智能技术大会(https://ml-summit.org) 传统基准测试工具(如SPEC CPU、SysBench)面向通用计算负载设计,其工作负载建模、指标维度与调度语义已无法刻画AI原生软件的核心行为特征…...

openclaw平替之nanobot源码解析(六):子智能体(Subagents)试

插件化架构 v3 版本最大的变化是引入了模块化插件系统。此前版本中集成在核心包里的原生功能,现在被拆分成独立的插件。 每个插件都是一个独立的 Composer 包,包含 Swift 和 Kotlin 代码、权限清单以及原生依赖。开发者只需安装实际用到的插件&#xff0…...

iStore:为OpenWRT打造的轻量级软件中心,让插件安装变得像点菜一样简单

iStore:为OpenWRT打造的轻量级软件中心,让插件安装变得像点菜一样简单 【免费下载链接】istore 一个 Openwrt 标准的软件中心,纯脚本实现,只依赖Openwrt标准组件。支持其它固件开发者集成到自己的固件里面。更方便入门用户搜索安装…...

为什么你的Mono.delay()在Loom下延迟翻倍?深入HotSpot虚拟线程调度器源码,定位Reactor 3.6.5+JDK21的3处隐式阻塞点

第一章:Java 项目 Loom 响应式编程转型指南Project Loom 为 Java 带来了轻量级虚拟线程(Virtual Threads)和结构化并发能力,与响应式编程范式(如 Project Reactor 或 RSocket)并非互斥,而是互补…...

告别手动拖拽!用Python脚本pydcs批量生成DCS World飞行任务(附完整代码)

用Python解放双手:pydcs自动化生成DCS World飞行任务全攻略 当你在DCS World中反复拖拽AI单位、手动设置航点时,是否想过这些机械操作其实可以用几行代码解决?对于追求效率的任务设计师来说,pydcs这个Python库就像给你的任务编辑器…...

从“代工标签”到“世界主场”:海信这9年,藏着中国品牌全球化的顶级逻辑

明明产品实力不输海外大牌,却只能靠低价换取市场份额;砸重金签约全球红人,曝光量上去了,转化率却始终在冰点徘徊;想要摆脱“代工宿命”冲击高端市场,却发现连全球用户的文化和语言门槛都难以跨越。 这是当…...

告别拼图噩梦:这款开源工具如何用3行代码搞定显微图像拼接?

告别拼图噩梦:这款开源工具如何用3行代码搞定显微图像拼接? 【免费下载链接】MIST Microscopy Image Stitching Tool 项目地址: https://gitcode.com/gh_mirrors/mist3/MIST 你是否曾为处理数百张高分辨率显微图像而彻夜难眠?当细胞培…...

快速构建精简Windows 11系统:tiny11builder完整使用指南

快速构建精简Windows 11系统:tiny11builder完整使用指南 【免费下载链接】tiny11builder Scripts to build a trimmed-down Windows 11 image. 项目地址: https://gitcode.com/GitHub_Trending/ti/tiny11builder 你是否厌倦了臃肿的Windows 11系统&#xff1…...

CSL编辑器实战指南:3种学术场景下的高效引用样式管理方案

CSL编辑器实战指南:3种学术场景下的高效引用样式管理方案 【免费下载链接】csl-editor cslEditorLib - A HTML 5 library for searching and editing CSL styles 项目地址: https://gitcode.com/gh_mirrors/csl/csl-editor CSL编辑器是一款基于HTML5的引用样…...