
一、Shell 脚本基础1. 脚本概念与应用场景核心概念Shell 脚本是将一系列 Linux 命令按执行顺序保存在.sh后缀的文件中赋予执行权限后配合分支、循环等控制语句实现批量、自动化处理的脚本程序。典型应用场景服务批量部署系统状态监控定时数据备份日常自动化运维2. 脚本结构与执行方式标准脚本结构bash#!/bin/bash # 注释脚本功能、版本、作者说明 # 以下为具体执行的命令 echo Hello Shell Script#!/bin/bash声明脚本解析器指定用 bash 解释执行必须写在文件第一行#单行注释脚本执行时会忽略注释内容4 种执行方式bash# 方式1解释器直接执行无需执行权限开启子Shell运行 sh test.sh bash test.sh # 方式2路径执行需先赋予执行权限 chmod x test.sh ./test.sh # 相对路径执行 /root/test.sh # 绝对路径执行 # 方式3点号执行当前Shell环境执行变量会生效 . test.sh # 方式4source执行同点号当前Shell加载变量 source test.sh注释方式 3、4 会将脚本内变量加载到当前终端环境方式 1、2 在子 Shell 中运行不影响当前环境变量。语法检测命令bashsh -n test.sh # 作用仅检查脚本语法错误不实际执行脚本3. 输入输出与重定向基础输入输出bash# 输出命令 echo 这是一行输出内容 # 输入命令读取用户输入并赋值给变量 read -p 请输入用户名 username echo 欢迎你$username # -p指定输入前的提示文字重定向符号表格符号类型作用说明覆盖输出重定向将命令正确输出写入文件覆盖原有内容追加输出重定向将命令正确输出追加到文件末尾2错误输出重定向将命令报错信息写入文件全量输出重定向正确输出 错误输出统一写入文件输入重定向将文件内容作为命令的输入对象bash# 示例覆盖写入文件 echo 测试内容 a.txt # 示例错误日志收集 ls /不存在的路径 2 error.log # 示例here文档批量写入文件 cat test.txt EOF 第一行内容 第二行内容 第三行内容 EOF # 注释EOF为自定义分界符遇到相同分界符结束输入 # 若分界符加单引号 EOF则不解析变量所见即所得4. 变量体系变量定义规则格式变量名变量值等号两侧绝对不能有空格变量名只能由字母、数字、下划线组成不能以数字开头变量分类与用法1自定义变量bash# 定义变量 namezhangsan age22 # 调用变量$变量名 或 ${变量名}推荐加{}避免歧义 echo $name echo 年龄${age}岁2三种引号的区别bashnametom # 单引号强引用所见即所得不解析任何变量和特殊符号 echo 名字是$name # 输出名字是$name # 双引号弱引用可以解析变量 echo 名字是$name # 输出名字是tom # 不加引号解析所有特殊符号支持通配、命令替换 echo $name $age3系统环境变量操作系统预定义的全局变量常用示例bashecho $PATH # 命令搜索路径 echo $HOME # 当前用户家目录 echo $USER # 当前用户名 echo $HOSTNAME # 主机名4全局变量与局部变量全局变量整个 Shell 环境都可访问局部变量仅函数 / 脚本内部有效用local关键字声明5位置变量执行脚本时向脚本内部传递的参数bash# 脚本内写法test.sh echo 脚本名称$0 echo 第1个参数$1 echo 第2个参数$2 echo 第10个参数${10} # 超过9个参数必须加{} # 执行命令sh test.sh apple banana orange # 输出对应参数值6预定义变量Shell 内置固定含义的特殊变量表格变量含义说明$#统计传入脚本的参数总个数$*列出所有参数整体作为一个字符串$列出所有参数每个参数为独立个体$$获取当前脚本的进程号 PID$?上一条命令的执行返回值0 成功非 0 失败bash# 示例脚本 echo 参数总数$# echo 全部参数$ echo 进程PID$$5. 算术运算Shell 默认不支持直接数学运算需通过特定方式实现。常用运算符加、-减、*乘、/除、%取余取模4 种运算实现方式basha10 b3 # 方式1expr 命令 # 注意运算符两侧必须有空格乘号需要转义 \* resultexpr $a $b echo $result # 输出13 # 方式2let 命令 let sum$a$b echo $sum # 方式3双括号 (( )) 最常用写法 echo $((a*b)) # 输出30 echo $((a%b)) # 输出1 # 方式4bc 命令唯一支持小数运算 echo scale2; 10/3 | bc # scale2 表示保留2位小数6. 条件判断1文件 / 目录判断表格选项作用说明-d判断目标是否为目录 / 目录是否存在-f判断目标是否为文件 / 文件是否存在-e判断目标是否存在文件、目录通用-r判断文件是否可读-w判断文件是否可写-x判断文件是否可执行bash# 示例判断/root是否为目录 [ -d /root ] echo 是目录 || echo 不是目录 # 注释中括号 [] 两侧必须有空格2整数比较运算符表格选项英文全称含义-gtgreater than大于-ltless than小于-eqequal等于-gegreater equal大于等于-leless equal小于等于-nenot equal不等于bash# 示例判断10是否大于5 [ 10 -gt 5 ] echo 大于3逻辑运算符表格符号含义使用场景-a并且and写在单个 [] 内部-o或者or写在单个 [] 内部并且连接两个命令 / 判断前成功才执行后或者连接两个命令 / 判断前失败才执行后!非取反条件取反bash# 示例多条件并列判断 age25 [ $age -gt 18 -a $age -lt 30 ] echo 青年7. 流程控制if 分支语句单分支结构bashif 条件;then 条件成立时执行的命令 fibash# 示例判断文件是否存在 if [ -f test.txt ];then echo 文件存在 fi双分支结构bashif 条件;then 条件成立执行 else 条件不成立执行 fibash# 示例数字大小判断 num15 if [ $num -gt 10 ];then echo 数字大于10 else echo 数字小于等于10 fi多分支结构bashif 条件1;then 条件1成立执行 elif 条件2;then 条件2成立执行 elif 条件3;then 条件3成立执行 else 所有条件都不成立时执行 fibash# 示例体重分级判断 weight85 if [ $weight -ge 100 ];then echo 过重 elif [ $weight -ge 90 ];then echo 有点胖 elif [ $weight -ge 80 ];then echo 黄金身材 else echo 太瘦 fi注释if 判断具有阻塞性匹配到第一个符合条件的分支后不再向下判断后续条件。8. 流程控制for 循环基础语法bashfor 变量 in 取值范围 do 循环体命令 done4 种取值方式bash# 方式1列举式取值 for i in apple banana orange do echo 水果$i done # 方式2序列式 {} for i in {1..10} # 生成1到10的整数序列 do echo $i done # 方式3命令结果取值 for user in cat /etc/passwd | head -5 do echo $user done # 方式4C语言风格 for ((i1; i10; i)) do echo 第$i次循环 done9. 流程控制while 循环基础语法bashwhile 循环条件 do 循环体命令 done两大常用场景bash# 场景1按行读取文件内容 while read line do echo 行内容$line done test.txt # 场景2死循环 while : do echo 死循环运行中按CtrlC停止 sleep 1 done # 等价写法while true; do ... done10. 流程控制case 多分支语句语法格式bashcase $变量名 in 匹配模式1) 模式1对应的执行命令 ;; 匹配模式2) 模式2对应的执行命令 ;; *) 所有模式都不匹配时执行 ;; esacbash# 示例简易选择菜单 read -p 请输入数字(1-3): num case $num in 1) echo 你选择了选项1 ;; 2) echo 你选择了选项2 ;; 3) echo 你选择了选项3 ;; *) echo 输入错误请输入1-3 ;; esac注释每个分支结尾必须写;;代表跳出 case*是通配符匹配所有情况。二、sed 文本处理工具1. 基础介绍sed 是流式编辑器核心能力是对文本进行增、删、改、查支持正则匹配可直接修改源文件。基础语法bashsed [选项] 处理动作 文件名常用选项表格选项作用说明-n取消默认全量输出只输出匹配处理的行-i直接修改源文件不加 - i 仅在内存修改不影响原文件-e支持同时执行多个编辑指令-r开启扩展正则表达式支持2. 核心四大操作1查打印 pbash# 打印第3行 sed -n 3p test.txt # 打印第2到第5行 sed -n 2,5p test.txt # 打印第2行和第5行 sed -n 2p;5p test.txt # 打印包含字符串root的行 sed -n /root/p test.txt2增a 追加 /i 插入a在指定行后面追加内容i在指定行前面插入内容bash# 在第2行后面追加一行内容 sed 2a 这是追加的新内容 test.txt # 在包含hello的行前面插入内容 sed /hello/i 插入的内容 test.txt # 给每一行行首添加#注释 sed s/^/#/ test.txt # 给每一行行尾添加注释标记 sed s/$/ #注释/ test.txt3删删除 dbash# 删除第3行 sed 3d test.txt # 删除第2到第4行 sed 2,4d test.txt # 删除包含error的行 sed /error/d test.txt # 删除所有空行 sed /^$/d test.txt4改c 整行替换 /s 字符串替换c整行内容替换s行内字符串替换bash# 整行替换第3行替换为全新内容 sed 3c 全新的行内容 test.txt # 替换每行第一个old为new sed s/old/new/ test.txt # 全局替换替换所有old为new sed s/old/new/g test.txt # 只替换第3到第5行内的old sed 3,5s/old/new/g test.txt注释替换语法s#原内容#新内容#g中分隔符可用/#等内容含/时推荐用#避免转义。3. 分组与反向引用用()对内容分组通过\1 \2反向引用分组匹配的内容bash# 示例提取网卡IP地址 ip a | sed -n 9p | sed -r s#(.*)inet (.*)/24 (.*)#\2# # 注释 # -r 开启扩展正则支持()分组 # \2 引用第二个括号匹配到的内容即IP地址部分4. 实战抓取本机 IP 地址bash# 方法1sed纯提取 ip a | sed -n /inet /p | sed -r s#.*inet (.*)/24.*#\1# | grep -v 127.0.0.1 # 方法2grep正则配合 ip a | grep -Eo ([0-9]{1,3}\.){3}[0-9]{1,3} | grep -Ev 127|255三、awk 文本处理工具1. 基础介绍awk 是强大的结构化文本处理工具支持横向按行过滤、纵向按列提取尤其适合处理表格类、分隔符类文本。四种语法格式bash# 格式1基础格式 awk 模式{动作} 文件名 # 格式2指定列分隔符 awk -F 分隔符 模式{动作} 文件名 # 格式3指定多个分隔符贪婪匹配 awk -F [分隔符集合] 模式{动作} 文件名 # 表示贪婪模式多个连续分隔符视为一个 # 格式4完整三段式 awk -F 分隔符 BEGIN{初始化动作} 模式{逐行动作} END{收尾动作} 文件名BEGIN{}处理文件前执行仅执行 1 次常用于设置变量、打印表头中间模式{动作}逐行处理每行执行一次END{}所有行处理完后执行仅执行 1 次常用于统计、输出总结2. 内置变量表格变量含义说明NR行号Number of Record当前处理的是第几行NF列数Number of Field当前行总列数$n第 n 列内容$1第一列$NF代表最后一列FS输入列分隔符作用同 - F优先级高于 - FOFS输出列分隔符RS输入行分隔符默认换行符ORS输出行分隔符默认换行符bash# 示例打印行号和第一列内容 awk {print NR, $1} test.txt # 示例冒号分隔打印用户名和登录shell awk -F : {print $1, $NF} /etc/passwd # 示例生成CSV格式表格 awk -F [:/ ] BEGIN{print name,bash}{print $1,$NF} 1.txt 6.csv # 注释BEGIN先输出表头逐行输出内容最终重定向为csv文件3. 模式匹配条件1行号比较表达式bash# 打印第3行 awk NR3{print} test.txt # 打印第2到第5行 awk NR2 NR5{print} test.txt # 打印第2行之前和第5行之后 awk NR2 || NR5{print} test.txt2正则表达式匹配表格正则写法含义说明/^字符/匹配以指定字符开头的行/字符$/匹配以指定字符结尾的行/./匹配任意一个字符/?/匹配前一个字符 0 次或 1 次//匹配前一个字符 1 次及以上$n~/正则/指定第 n 列匹配正则bash# 匹配以root开头的行 awk /^root/ /etc/passwd # 匹配第三列以41开头的行 awk -F : $3~/^41/ /etc/passwd4. 实战练习题捐款数据场景测试数据说明reg.txt 第 1 列 姓氏第 2 列 名字第 3 列 ID 号码第 4/5/6 列 三次捐款金额题 1显示姓 Zhang 的人的第二次捐款金额及姓名bashawk -F [ :] /Zhang/{print $1$2, $5} reg.txt # 注释分隔符为空格冒号$1$2拼接全名$5是第二次捐款题 2显示 Xiaoyu 的名字和 ID 号码bashawk -F [ :] $2~/Xiaoyu/{print $1$2, $3} reg.txt # 注释$2~/Xiaoyu/ 精确匹配第二列为Xiaoyu的行题 3显示所有以 41 开头的 ID 对应的全名和 IDbashawk -F [ :] $3~/^41/{print $1$2, $3} reg.txt # ^41 表示字符串以41开头题 4显示所有以 D 或 X 开头的人名全名bashawk -F [ :] $2~/^D|^X/{print $1$2} reg.txt # ^D|^X 匹配以D开头 或以X开头题 5显示 ID 最后一位是 1 或 5 的人的全名bashawk -F [ :] $3~/[15]$/{print $1$2} reg.txt # [15]$ 表示以1或5结尾题 6显示 Xiaoyu 的捐款每个金额前加 $ 符号bashawk -F [ :] $2~/Xiaoyu/{print $$4, $$5, $$6} reg.txt题 7显示所有人全名格式为 姓名bashawk -F [ :] {print $1,$2} reg.txt5. awk 数组基础awk 中的数组本质是键值对集合元素具有天然唯一性常用于去重、统计次数。bash# 基础示例数组赋值与取值 awk BEGIN{ arr[0]apple arr[1]banana print arr[0] }特性数组下标可以是数字也可以是字符串元素不重复典型应用为日志 IP 去重、访问次数统计。