目录
- 一、if语句:你以为简单其实暗藏杀机
- 1. 基础语法(看似简单却容易踩坑)
- 2. 安全写法规范(企业级建议)
- 二、条件测试的六大门派
- 1. 文件测试(运维最爱)
- 2. 字符串比较(引号是灵魂)
- 3. 数字比较(别再用>了!)
- 三、case语句:比if更优雅的多路分支
- 1. 基础用法(菜单系统必备)
- 2. 高级模式匹配(支持通配符)
- 四、实战:智能文件处理器
- 五、避坑指南:生产环境经验
- 1.总是检查返回值:
- 2.防御性编程:
- 3.避免过度嵌套:
- 六、性能优化技巧
- 1. 条件顺序优化
- 2. 使用case代替多层if
- 课后挑战:智能日志分析器
开篇:当你的脚本需要做选择
想象你在教机器人泡咖啡:
- 直线脚本:只会按固定步骤操作(烫伤顾客预警!)
- 智能脚本:能判断"如果糖不够,就提醒补货"、“当水温>90℃时停止加热”
今天我们要把这种决策能力赋予Shell脚本,让你告别"一根筋"式编程!
一、if语句:你以为简单其实暗藏杀机
1. 基础语法(看似简单却容易踩坑)
if [ 条件 ]; then命令
elif [ 条件 ]; then命令
else命令
fi
经典错误案例:
# 错误1:忘记then
if [ -f file.txt ]echo "存在" # 会报错# 错误2:多余分号
if [ -d dir ]; then; # 多了一个分号echo "存在"
fi
2. 安全写法规范(企业级建议)
# 推荐风格:then换行,条件加空格
if [[ -f "/etc/passwd" ]]
thenecho "关键文件存在"
fi
二、条件测试的六大门派
1. 文件测试(运维最爱)
[ -e "/path" ] # 存在即可(文件/目录都行)
[ -S "/tmp/mysql.sock" ] # 是否是socket文件
[ -N "/etc/hosts" ] # 文件是否被修改过
2. 字符串比较(引号是灵魂)
name=""
[ -z "$name" ] && echo "姓名为空" # 判断空字符串
[ -n "$PATH" ] || echo "PATH居然为空?" # 判断非空
3. 数字比较(别再用>了!)
[ 10 -gt 5 ] # 大于
[ $? -eq 0 ] # 判断上条命令是否成功
[ $RANDOM -lt 10000 ] && echo "幸运数字"
三、case语句:比if更优雅的多路分支
1. 基础用法(菜单系统必备)
read -p "输入命令(start|stop|restart): " cmd
case "$cmd" instart)echo "服务启动中...";;stop)echo "服务停止中...";;*)echo "无效命令!"exit 1;;
esac
2. 高级模式匹配(支持通配符)
case "$HOSTNAME" innode[1-9])echo "这是集群节点";;db-*)echo "这是数据库服务器";;
esac
四、实战:智能文件处理器
#!/bin/bash
# 根据文件类型自动处理file="$1"if [[ ! -e "$file" ]]; thenecho "错误:文件不存在" >&2exit 1
ficase $(file -b "$file") in*"ASCII text"*)echo "文本文件 - 显示前5行:"head -n 5 "$file";;*"Zip archive"*)echo "压缩包 - 查看内容:"unzip -l "$file" | head -10;;*"PDF"*)echo "PDF文件 - 提取文本:"pdftotext "$file" - | head -n 10;;*)echo "未知文件类型";;
esac
运行效果:
$ ./file_proc.sh test.pdf
PDF文件 - 提取文本:
Chapter 1
Introduction to Shell...
五、避坑指南:生产环境经验
1.总是检查返回值:
if ! cp file1 file2; thenecho "复制失败!" >&2exit 1
fi
2.防御性编程:
dir="/data/logs"
[ -d "$dir" ] || mkdir -p "$dir" || exit 1
3.避免过度嵌套:
# 不好:
if [ 条件1 ]; thenif [ 条件2 ]; then...fi
fi# 更好:
[ 条件1 ] && [ 条件2 ] && 命令
六、性能优化技巧
1. 条件顺序优化
# 把高概率条件放前面
if [[ $RANDOM -lt 1000 ]]; thenecho "小概率事件"
elif [[ $RANDOM -gt 10000 ]]; thenecho "常见情况"
fi
2. 使用case代替多层if
# 测试速度差异(case通常更快)
time {for i in {1..1000}; docase "$i" in1) ;; 2) ;; ...esacdone
}
课后挑战:智能日志分析器
需求:
- ✅ 分析/var/log/syslog(或其他日志)
- ✅ 根据关键词(ERROR/WARNING等)统计出现次数
- ✅ 用不同颜色输出不同级别日志
进阶要求:
- ⚠️ 当日志文件过大时(>100MB)自动启用less查看
示例输出:
$ ./log_analyzer.sh
ERROR : 15次 (显示红色)
WARNING: 28次 (显示黄色)