Shell編程核心入門:參數傳遞、運算符與流程控制全解析
在Linux/Unix系統中,Shell作為命令解釋器和腳本語言,是自動化運維、批量處理任務的核心工具。掌握Shell腳本的參數傳遞、運算符使用和流程控制,能讓你從“手動執行命令”升級為“編寫腳本自動完成復雜任務”。本文將結合實例,詳細拆解這三大核心知識點,助你快速入門Shell編程。
文章目錄
- Shell編程核心入門:參數傳遞、運算符與流程控制全解析
- 一、Shell參數傳遞:讓腳本更靈活
- 1.1 基礎:參數傳遞與獲取方式
- 傳遞參數的語法
- 腳本內獲取參數的語法
- 1.2 關鍵區別:$* vs $@
- 實例驗證
- 2.2 關系運算符:判斷數值大小
- 實例:比較兩個參數大小
- 2.3 邏輯運算符:組合條件判斷
- 實例:判斷數值是否在指定范圍
- 2.4 文件測試運算符:判斷文件屬性
- 實例:檢查腳本是否可執行
- 三、Shell流程控制:控制腳本執行邏輯
- 3.1 選擇結構:根據條件執行不同代碼
- 1. if語句:單支、雙支、多支判斷
- 實例:根據分數判斷等級
- 2. case語句:多值匹配判斷
- 實例:簡單菜單交互
- 四、綜合實例:Shell腳本實戰
- 五、總結
一、Shell參數傳遞:讓腳本更靈活
在執行Shell腳本時,我們可以通過命令行向腳本傳遞參數,實現“同一腳本處理不同數據”的需求。比如編寫一個計算兩個數之和的腳本,通過參數傳入不同數字,無需修改腳本即可得到結果。
1.1 基礎:參數傳遞與獲取方式
傳遞參數的語法
執行腳本時,參數緊跟在腳本名后,用空格分隔:
./腳本名 參數1 參數2 參數3 ...
例如:./calc.sh 10 20
表示向calc.sh
腳本傳遞參數10
和20
。
腳本內獲取參數的語法
腳本中通過$n
獲取第n
個參數(n
為數字),特殊變量用于獲取參數整體信息:
變量 | 含義 | 示例(以上述./calc.sh 10 20 為例) |
---|---|---|
$0 | 當前腳本的文件名 | $0 輸出 ./calc.sh |
$1~$n | 第1個到第n個參數 | $1 輸出 10 ,$2 輸出 20 |
$# | 傳遞的參數總數 | $# 輸出 2 |
$* | 所有參數的集合(作為一個整體字符串) | "$*" 輸出 "10 20" |
$@ | 所有參數的集合(作為獨立參數列表) | "$@" 輸出 "10" "20" |
1.2 關鍵區別:$* vs $@
$*
和$@
都表示“所有參數”,但被雙引號包裹時行為完全不同,這是Shell參數傳遞的高頻考點:
場景 | $*的行為 | $@的行為 |
---|---|---|
不被"" 包裹 | 均以$1 $2 ... $n 形式輸出參數列表 | 均以$1 $2 ... $n 形式輸出參數列表 |
被"" 包裹 | 合并為一個字符串:"$1 $2 ... $n" | 保持獨立參數:"$1" "$2" ... "$n" |
實例驗證
創建param_demo.sh
腳本:
#!/bin/bash
echo "=== \$* 演示 ==="
for arg in "$*"; doecho "參數:$arg"
doneecho "=== \$@ 演示 ==="
for arg in "$@"; doecho "參數:$arg"
done
執行腳本:./param_demo.sh 1 2 3
,輸出結果:
=== $* 演示 ===
參數:1 2 3
=== $@ 演示 ===
參數:1
參數:2
參數:3
結論:循環處理獨立參數時,優先使用"$@"
;需將所有參數作為整體字符串處理時,使用"$*"
。
## 二、Shell運算符:實現腳本的計算與判斷
Shell本身不支持直接數學運算,需通過工具(如`expr`)或特殊語法(如`$(( ))`)實現。運算符按功能分為**算術運算符**、**關系運算符**、**邏輯運算符**和**文件測試運算符**。### 2.1 算術運算符:處理數值計算
常用算術運算符:`+`(加)、`-`(減)、`*`(乘)、`/`(除)、`%`(取余)、`++`(自增)、`--`(自減)。#### 實現方式對比
| 方式 | 語法示例 | 說明 |
|--------------|-----------------------------------|---------------------------------------|
| `expr` | `val=`expr 2 + 2`` | 運算符兩邊必須有空格,用反引號``包裹 |
| `$(( ))` | `val=$((2+2))` | 支持運算符無空格,語法簡潔 |
| `$[ ]` | `val=$[2+2]` | 與`$(( ))`類似,兼容性稍差 |
| `let` | `let val=2+2` | 直接計算,無需`$`引用變量 |#### 實例:計算1-10的累加和
```bash
#!/bin/bash
sum=0
for ((i=1; i<=10; i++)); dosum=$((sum + i)) # 或 sum=$[sum+i]
done
echo "1-10累加和:$sum" # 輸出 55
2.2 關系運算符:判斷數值大小
關系運算符僅支持整數,返回true
(0)或false
(非0),常用于條件判斷。
運算符 | 含義 | 示例(a=10 ,b=20 ) |
---|---|---|
-eq | 等于 | [ $a -eq $b ] → false |
-ne | 不等于 | [ $a -ne $b ] → true |
-gt | 大于 | [ $a -gt $b ] → false |
-lt | 小于 | [ $a -lt $b ] → true |
-ge | 大于等于 | [ $a -ge $b ] → false |
-le | 小于等于 | [ $a -le $b ] → true |
實例:比較兩個參數大小
#!/bin/bash
a=$1
b=$2
if [ $a -gt $b ]; thenecho "$a > $b"
elif [ $a -lt $b ]; thenecho "$a < $b"
elseecho "$a == $b"
fi
執行:./compare.sh 15 20
→ 輸出 15 < 20
。
2.3 邏輯運算符:組合條件判斷
用于將多個條件組合,常見有兩種語法(注意場景區別):
邏輯關系 | if 語句中語法 | 直接計算語法 | 示例(a=10 ) |
---|---|---|---|
與(and) | -a | && | [ $a -gt 5 -a $a -lt 15 ] → true |
或(or) | -o | ` | |
非(not) | ! | ! | [ ! $a -eq 5 ] → true |
實例:判斷數值是否在指定范圍
#!/bin/bash
num=$1
if [ $num -ge 0 -a $num -le 100 ]; thenecho "$num 在 0-100 范圍內"
elseecho "$num 超出范圍"
fi
2.4 文件測試運算符:判斷文件屬性
Shell腳本常需操作文件(如判斷文件是否存在、是否可執行),文件測試運算符是核心工具:
運算符 | 含義 | 示例 |
---|---|---|
-e | 文件/目錄是否存在 | [ -e ./test.sh ] |
-f | 是否為普通文件 | [ -f ./test.sh ] |
-d | 是否為目錄 | [ -d ./test_dir ] |
-r | 是否可讀 | [ -r ./test.sh ] |
-w | 是否可寫 | [ -w ./test.sh ] |
-x | 是否可執行 | [ -x ./test.sh ] |
-s | 文件是否非空(大小>0) | [ -s ./test.sh ] |
實例:檢查腳本是否可執行
#!/bin/bash
file="./test.sh"
if [ -e $file ]; thenif [ -x $file ]; thenecho "$file 可執行,開始運行..."./$fileelseecho "$file 不可執行,添加執行權限..."chmod +x $filefi
elseecho "$file 不存在!"
fi
三、Shell流程控制:控制腳本執行邏輯
默認情況下,Shell腳本按“從上到下、逐行執行”的順序運行。流程控制語句可改變執行順序,分為選擇結構(if、case)和循環結構(for、while)。
3.1 選擇結構:根據條件執行不同代碼
1. if語句:單支、雙支、多支判斷
-
單支if:條件成立則執行,否則不執行;
if [ 條件 ]; then代碼塊 fi
-
雙支if:條件成立執行代碼1,否則執行代碼2;
if [ 條件 ]; then代碼塊1 else代碼塊2 fi
-
多支if:多條件判斷,匹配第一個成立的條件;
if [ 條件1 ]; then代碼塊1 elif [ 條件2 ]; then代碼塊2 else默認代碼塊 fi
實例:根據分數判斷等級
#!/bin/bash
score=$1
if [ $score -ge 90 ]; thenecho "優秀"
elif [ $score -ge 80 ]; thenecho "良好"
elif [ $score -ge 60 ]; thenecho "及格"
elseecho "不及格"
fi
執行:./grade.sh 85
→ 輸出 良好
。
2. case語句:多值匹配判斷
當需要匹配“固定的多個值”時(如菜單選擇),case
比if-elif
更簡潔,語法如下:
case $變量 in模式1)代碼塊1;; # 結束當前模式模式2)代碼塊2;;*) # 默認模式(無匹配時執行)默認代碼塊;;
esac # case的反寫,標志結束
實例:簡單菜單交互
#!/bin/bash
echo "請選擇操作:1.查看日期 2.查看目錄 3.退出"
read choice # 讀取用戶輸入
case $choice in1)date;;2)ls;;3)echo "退出程序"exit 0 # 退出腳本;;*)echo "無效選擇";;
esac
四、綜合實例:Shell腳本實戰
結合上述知識點,編寫一個“批量文件重命名”腳本:需求是將當前目錄下所有.txt
文件重命名為file_1.txt
、file_2.txt
…
#!/bin/bash
# 批量重命名.txt文件
count=1 # 計數器,用于文件名編號# 遍歷當前目錄下的.txt文件
for file in *.txt; do# 判斷是否為普通文件(避免目錄干擾)if [ -f $file ]; then# 重命名文件mv $file "file_$count.txt"echo "已重命名:$file → file_$count.txt"count=$((count + 1)) # 計數器自增fi
doneecho "重命名完成,共處理 $((count-1)) 個文件"
五、總結
Shell編程的核心是“通過參數傳遞實現靈活性、通過運算符實現計算判斷、通過流程控制實現邏輯跳轉”。掌握本文的三大知識點后,你可以:
- 編寫支持命令行參數的腳本;
- 實現數值計算、文件判斷等核心功能;
- 用流程控制語句處理復雜邏輯(如批量任務、交互菜單)。
建議從“小腳本”開始練習(如文件備份、日志清理),逐步積累實戰經驗,最終實現Shell自動化運維的目標!