Linux

Bash 程式設計教學與範例:for 迴圈

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

參考資料:nixCraftTsung’s BlogBenjr.twLinux HintTLDP

Share
Published by
Office Guide
Tags: Bash

Recent Posts

Python 使用 PyAutoGUI 自動操作滑鼠與鍵盤

本篇介紹如何在 Python ...

9 個月 ago

Ubuntu Linux 以 WireGuard 架設 VPN 伺服器教學與範例

本篇介紹如何在 Ubuntu ...

9 個月 ago

Linux 網路設定 ip 指令用法教學與範例

本篇介紹如何在 Linux 系...

9 個月 ago

Windows 使用 TPM 虛擬智慧卡保護 SSH 金鑰教學與範例

本篇介紹如何在 Windows...

10 個月 ago

Linux 以 Shamir’s Secret Sharing 分割保存金鑰教學與範例

介紹如何在 Linux 中使用...

10 個月 ago

Linux 以 Cryptsetup、LUKS 加密 USB 隨身碟教學與範例

介紹如何在 Linux 系統中...

10 個月 ago