介紹如何在 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 則代表主機有回應,否則就是有問題。
