Shell 腳本的循環控制(for

熟悉其他高級語言的夥伴們肯定了解循環控制語法是編程中非常基礎的內容,今天就介紹Shell 中設計循環控制的語法,for/while/until 等內容。

for 命令

for 命令是最簡單的循環控制語句,它的格式為:

for var in list
do
commands
done

語法比較簡單,不做冗餘的介紹了,直接上例子:

Shell 腳本的循環控制(for/while/until)

圖1

輸出結果:
The next brand is MacOS
The next brand is Windows
The next brand is Linux
The next brand is Unix
The next brand is Deepin
The last brand is Deepin
The modified brand is Deepin

從圖1 中;item 作為臨時變量在 ”MacOS WIndows Linux Unix Deepin"列表中循環賦值,然後循環執行do 至 done 之間的語句。這裡值得注意的是:item 作為 for 循環的局部變量(或者是棧變量)在循環體外依然可以訪問,例如在done 退出循環體後,依然可以訪問 item 這個for循環體內的局部變量,這個是和其他高級語言不太相同的。具有高級語言的夥伴們可能第一次會覺得有些奇怪,不過這是Shell 語言的特點,這和C++那些聲明式的高級語言是有區別的。在C++中所有變量使用前必須要聲明類型,而在Shell 中卻沒有這樣的規定。for 循環中的列表可以有多種形式,可以像圖1中那樣直接枚舉,也可以定義成一個變量,也可以通過命令的返回作為 list 對象(例如可以通過cat file將file中的內容作為list返回)這裡就不一一舉例了。

修改字段分隔符

上面的例子中,我們發現,list使用過空格來作為分隔符的。那麼是什麼決定用空格作為list分隔符的呢。其實這裡是通過環境變量 IFS (internal field separator) bash shell 的分隔符默為:

  • 空格
  • 製表符
  • 換行符

默認的分隔符優惠會造成麻煩,尤其是需要處理的數據中包含空格時。例如

Shell 腳本的循環控制(for/while/until)

文件名為:my_file

如圖,第二行"New York"中包含了空格,所以for 循環式,“New York”會被認為兩個元素。此結果並不是我們想要的。這是我們可以修改 IFS 只為換行符,來規避這種情況。

IFS=$'\n':; #可以一次指定多個符號作為分隔符,只需要將符號串聯一起。此例子中換行符,冒號和分號都作為分隔符。
Shell 腳本的循環控制(for/while/until)

圖2

輸出結果:
value is China
value is New York
value is London
value is Japan

圖2中,我們修改IFS前先將舊的IFS保存下來,然後在適當的地方恢復,這對於腳本中部分邏輯需要恢復默認的 IFS 時提供了方法。

while 命令

while 命令其實是 if-then 和 for 循環的結合體。格式如下:

while test command
do
commands
done

當 "test command" 返回碼為 0 時,do 後的commands 會循環執行。此處應該注意的是:"test command" 需要在 do 的執行過程中發生變化,否則while循環將會無法停止。

until 命令

until 命令和 while 命令工作方式完全相反,until 是等到命令的返回碼不為0 時,才執行循環體中的命令,格式如下:

until test commands
do
other commands
done

上例子:

Shell 腳本的循環控制(for/while/until)

圖3

圖3中 until 後判斷var1 是否為0, 不為零是, 表達式返回碼為非 0 ,此時執行do 循環體內的命令,當 var1 為0 時, 返回碼為0, 此時until 循環結束。

循環控制

break 命令:是退出當前循環的簡單命令。

Shell 腳本的循環控制(for/while/until)

圖4

輸出結果
the number is 1
the number is 2
the number is 3
The loop is completed

從圖4中可以看出,當 var==4 時,for 循環會滿足break 條件而退出。break 也適合while 和 until 的循環。break 的默認規則和其他語言,例如C/C++相同,只會退出當前的循環,如果出現循環嵌套,那麼只會退出break 所在的循環。

break 跳出外部循環

break 語句除了默認的跳出當前循環,還能控制跳出外部循環,這是C/C++語言沒有的特性。語法格式為:

break n #n為1則是跳出當前循環,n為2 則是跳出上一級循環

上例子:

Shell 腳本的循環控制(for/while/until)

圖5

輸出結果:

Outer loop: 1
Inner loop:1

Inner loop:2
Inner loop:3
Inner loop:4

從圖5中可以看出是一個嵌套循環,在內部循環中,當b大於4時,"break 2" 會跳出上一級循環,所以外部循環只執行一次就被內部循環的break 語句退出了。這種用法在其他語言中不太常見,而且也不是特別推薦的用法。因為推出外部循環處理不當,可能會產生異非想要的結果。

continue 命令

continue 的原理和C/C++相同,會提前終止循環,但是不會退出循環。對於沒有編程經驗的小夥伴,聽起來有點繞,可以理解為程序邏輯的短路行為。直接上代碼:

Shell 腳本的循環控制(for/while/until)

圖6

輸出結果為:
the number is 1
the number is 2
the number is 3
the number is 4
the number is 5
the number is 10
the number is 11
the number is 12
the number is 13
the number is 14

如圖6, continue 命令會跳過 5<var1>

continue 短路外部循環

continue 也有 break 類似的控制外部循環的命令,語法格式為:

continue n #短路到外部n層嵌套循環

例子和 ‘break n’類似,這裡就不再贅述了。

循環語句在實際工作中是非常有用的,例如你想創建多個用戶,那麼就可以在所有用戶名存儲在文件中,然後寫個shell腳本去讀取文件,然後通過循環操作依次去除用戶名,然後再通過 useradd 命令添加用戶。所有命令在 shell腳本中執行,一氣呵成,非常便利。

/<var1>


分享到:


相關文章: