第4章 Shell脚本与自动化:变量、循环、正则、调试技巧与编写场景
Shell脚本是Linux运维交付工程师的“肌肉记忆”,面试中高频考察变量作用域、循环控制、正则匹配、调试手段及实战脚本设计。本章围绕三大核心问答,帮你构建从语法到工程化的完整回答框架。
核心知识表:Shell脚本调试技巧对比
| 调试方式 | 命令/语法 | 适用场景 | 注意事项 |
|---|---|---|---|
| 逐语句跟踪 | set -x 或 bash -x script.sh |
定位变量赋值、分支判断 | 输出冗长,生产慎用 |
| 错误即停止 | set -e |
防止错误无声继续 | 管道中需用 set -o pipefail |
| 退出陷阱 | trap 'cmd' EXIT/ERR |
清理临时文件、记录日志 | 避免在陷阱中再次触发陷阱 |
| 手动日志 | echo "DEBUG: ..." |
重要变量/步骤监控 | 上线前清理调试输出 |
面试问题1:请编写一个Shell脚本,批量检查多个主机的网络连通性
考察点:循环遍历、if条件判断、ping命令使用、输出格式化、超时设置。
回答框架:① 定义主机列表(数组或文件);② for循环遍历;③ ping -c 1 -W 2 检测;④ 根据返回值输出“可达/不可达”;⑤ 可选:输出汇总报告。
示例回答:
#!/bin/bash
hosts=("192.168.1.1" "192.168.1.2")
for ip in "${hosts[@]}"; do
if ping -c 1 -W 2 "$ip" &>/dev/null; then
echo "$ip: OK"
else
echo "$ip: FAIL"
fi
done
可能追问:如何并行检查多个主机?你如何防止脚本卡死?
避坑提醒:不要在脚本内硬编码密码或敏感信息;生产环境使用超时参数(-W)避免僵尸进程。
面试问题2:如何在Shell脚本中处理字符串替换和正则匹配?举例说明
考察点:sed/awk/grep基础、正则表达式的熟练度、变量替换(Bash内置)。
回答框架:① 明确需求(替换/提取/校验);② 选择工具:简单替换用 ${var//old/new};③ 复杂匹配用 sed -E 或 grep -P;④ 测试正则避免回溯陷阱。
示例回答:
# 变量替换
str="hello world"
echo "${str//world/WORLD}" # hello WORLD
# 正则提取IP
ip=$(echo "IP: 10.0.0.1" | grep -oP '\d+\.\d+\.\d+\.\d+')
可能追问:贪婪匹配与非贪婪匹配的区别?在sed中如何实现非贪婪?
避坑提醒:注意转义字符:sed中使用 \{ 表示数量,grep -P 需要PCRE支持;生产环境慎用 eval。
面试问题3:你在编写Shell脚本时如何进行调试?请说出至少三种方法
考察点:调试意识、set命令家族、trap使用、生产环境安全调试。
回答框架:① 开发期用 bash -x 或 set -x 查看执行过程;② 关键点位加 echo 输出变量值;③ 用 set -e 捕获未处理错误;④ 用 trap '...' EXIT 保证清理。
示例回答:“我通常先用
bash -x script.sh 跟踪每一步,发现变量异常后改用 set -x 只调试问题区间;再配合 set -e -o pipefail 确保错误不扩散;最后用 trap 'rm -f /tmp/xxx' EXIT 清理临时文件。”可能追问:生产环境如何安全调试?如果脚本已经上线,如何定位资源泄漏?
避坑提醒:禁止在生产环境直接使用 set -x 输出敏感信息;调试完成后务必删除调试语句;使用 trap 时注意不要覆盖内置信号。
面试加分点:提到
shellcheck 静态分析工具,展示工程化习惯;主动说明使用 getopts 处理命令行参数;提到将常变参数抽取为配置文件,避免硬编码。
高频陷阱提醒:
• 变量未引号包裹导致空格分裂 → 永远使用
• 循环内修改全局变量未预期 → 使用
• 正则中使用
• 管道后变量赋值丢失 → 使用
• 变量未引号包裹导致空格分裂 → 永远使用
"$var"• 循环内修改全局变量未预期 → 使用
local 声明局部变量• 正则中使用
[* 未转义 → 用 [\*] 或字符类• 管道后变量赋值丢失 → 使用
shopt -s lastpipe 或进程替换