介紹如何在 bash shell 中使用 for
迴圈,處理重複性的工作。
在 bash shell 中若需要執行重複性的指令,可以運用迴圈來處理,以下是 bash shell 中幾種
for
迴圈的用法以及範例程式碼。
固定疊代次數
如果迴圈的疊代範圍(開始與結束)是固定的,可以運用 bash 的 brace expansion 功能,以起始與結束兩個數值設定,快速產生連續的數列,放入 for
迴圈中使用:
# 變數 i 從 1 疊代至 5 for i in {1..5} do echo "i = ${i}" done
i = 1 i = 2 i = 3 i = 4 i = 5
brace expansion 功能除了設定起始與結束之外,也可以設定每次增加的數值,例如從 1
疊代至 9
,每次增加 2
:
# 變數 i 從 1 疊代至 9,每次增加 2 for i in {1..9..2} do echo "i = ${i}" done
i = 1 i = 3 i = 5 i = 7 i = 9
若將每次增加的數值設定為負數,即可以遞減的方式進行疊代:
# 變數 i 從 9 疊代至 1,每次減少 2 for i in {9..1..-2} do echo "i = ${i}" done
i = 9 i = 7 i = 5 i = 3 i = 1
動態疊代次數
如果需要在指令稿中動態指定 for
迴圈的起始與結束範圍,可以改用 seq
指令來產生疊代的數列:
# 變數 i 從 1 疊代至 5 FIRST=1 LAST=5 for i in $(seq $FIRST $LAST) do echo "i = ${i}" done
i = 1 i = 2 i = 3 i = 4 i = 5
seq
指令也可以指定每次增加的數值:
# 變數 i 從 1 疊代至 9,每次增加 2 FIRST=1 LAST=9 INCREMENT=2 for i in $(seq $FIRST $INCREMENT $LAST) do echo "i = ${i}" done
i = 1 i = 3 i = 5 i = 7 i = 9
亦可將增加的數值設為負數,以遞減的方式進行疊代:
# 變數 i 從 9 疊代至 1,每次減少 2 FIRST=9 LAST=1 INCREMENT=-2 for i in $(seq $FIRST $INCREMENT $LAST) do echo "i = ${i}" done
i = 9 i = 7 i = 5 i = 3 i = 1
疊代序列元素
bash shell 的 for
迴圈除了疊代數值的序列之外,也可以直接對一般性的序列元素進行疊代,例如:
# 疊代序列元素 for name in Ackley Bardo Carin do echo "Hello, ${name}." done
Hello, Ackley. Hello, Bardo. Hello, Carin.
也可以直接拿其他指令的輸出來進行疊代,例如:
# 對 ls 的輸出進行疊代 for f in `ls /` do echo "Found: $f" done
Found: bin Found: boot Found: dev [略]
雙括號語法迴圈
bash shell 的雙括號迴圈語法跟 C 語言的迴圈寫法非常類似,以下是一些範例:
# 變數 i 從 1 疊代至 5 for (( i=1; i<=5; i++ )) do echo "i = $i" done
i = 1 i = 2 i = 3 i = 4 i = 5
自己設定每次增加的數值:
# 變數 i 從 1 疊代至 9,每次增加 2 for (( i=1; i<=9; i+=2 )) do echo "i = $i" done
i = 1 i = 3 i = 5 i = 7 i = 9
以遞減的方式疊代:
# 變數 i 從 9 疊代至 1,每次減少 2 FIRST=9 LAST=1 STEP=2 for (( i=$FIRST; i>=$LAST; i-=$STEP )) do echo "i = $i" done
i = 9 i = 7 i = 5 i = 3 i = 1
跳過、中止疊代
在疊代的過程中,如果需要根據某些判斷條件來中止迴圈的執行,可以在迴圈中間插入 if
的判斷式,配合 break
中止迴圈的執行:
# 以 break 中止迴圈 for i in {1..5} do if (( $i > 3 )); then break fi echo "i = ${i}" done
i = 1 i = 2 i = 3
如果只是要根據判斷條件,跳過當次疊代,可以改用 continue
:
# 以 continue 跳過當次疊代 for i in {1..5} do if (( $i % 2 == 0 )); then continue fi echo "i = ${i}" done
i = 1 i = 3 i = 5
實際應用
以下是一個以 ping
指令結合 for
迴圈,來檢查各主機網路狀態的範例程式碼:
# 以 Ping 檢查各主機的網路狀態 network="192.168.211" for i in {1..5} do ping -c 1 -w 1 ${network}.${i} &> /dev/null if [ $? == 0 ]; then echo "${network}.${i} is up." else echo "${network}.${i} is down." fi done
192.168.211.1 is up. 192.168.211.2 is down. 192.168.211.3 is down. 192.168.211.4 is up. 192.168.211.5 is down.
這裡我們以 ping
檢測主機的網路狀態之後,從 $?
這個特殊的 bash 變數取得 ping
的執行結果,如果結果是 0
則代表主機有回應,否則就是有問題。