目錄
- 一、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次 (顯示黃色)