天天看點

SHELL腳本程式設計進階(一)

本文部分資料和示例援引自以下書籍。在此,感謝原作者的創作,以及所有譯者的付出,向他們緻敬。

<a href="http://www.tldp.org/LDP/abs/html/" target="_blank">Advanced Bash-Scripting Guide</a>

<a href="https://linuxstory.gitbooks.io/advanced-bash-scripting-guide-in-chinese/content/" target="_blank">《進階Bash腳本程式設計指南》Revision 10中文版</a>

<a href="https://bash.cyberciti.biz/guide/Main_Page" target="_blank">Linux腳本程式設計執導</a>

在之前的文章中,我們已經詳細的介紹了SHELL腳本程式設計的一些基礎知識,運用這些基礎已經能夠幫助我們高效率的解決日常生産中的一些問題了,但還遠遠不夠。實際生産中可能面臨這大量的複雜的處理任務,需要我們編寫腳本去完成。此時就需要一些更進階的内容,來幫助我們完成對腳本的編寫。 今天将介紹的是SHELL腳本中的循環與分支
1. 分支 2. 循環 3. 循環控制 4. 特殊用法
if 語句是腳本編寫過程中基本分支語句。簡單的if語句可以使用一些測試結構代替,但是if語句的可讀性,卻是測試結構無法替代。

單分支的if語句

單分支的 if 語句的文法結構如下。

多分支的if語句

多分支的 if 語句的文法結構如下。
if 語句其實還是比較好了解的,它是對某一個條件進行判斷,然後根據判斷的結構進行其他的操作。稍微有點程式設計經驗的人,都會了解這種簡短的分支結構。  if 語句還可以嵌套,可以根據實際生産中的情況,合理的進行嵌套組合。

例子

判斷某個變量的值是否在0-5之間
判斷某個學員的學習成績,并輸出。不及格,及格,優秀等資訊。
在一些比較流行的程式設計語言中也有多分支的條件判斷語句,例如C/C++/JAVA中的switch語句,可以根據條件跳轉到其中的任意一個分支,很适合用來建立菜單。
case 語句的文法如下

注意

對變量進行引用不是必須的,因為在這裡不會進行字元分割 條件測試語句必須以右括号 ) 結束。 每一段代碼塊都必須以雙分号 ;; 結束。 如果測試條件為真,其對應的代碼塊将被執行,而後整個 <code>case</code> 代碼段結束執行 <code>case</code> 代碼段必須以 <code>esac</code> 結束(倒着拼寫case)。

case支援glob風格的通配符

*: 任意長度任意字元 ?: 任意單個字元 []: 指定範圍内的任意單個字元 <code>a|b</code>: a或b

示例

判斷使用者輸入的 是否是yes或者no(隻要是這兩個詞就可以,忽略大小寫)
實作簡單的通訊錄,輸入索引,能夠檢視詳細的資訊
檢視目前系統的裝置架構 是 i386 還是i486 或者是X86_64
select 語句嚴格來說不能算作循環,因為它們并沒有反複執行代碼塊。但是和循環結構相似的是,它們會根據代碼塊頂部或尾部的條件控制程式流。 select 結構的文法如下
如果不使用break指令,select 語句将變成無限循環,會重複的執行那些代碼段。 select 循環主要用于建立菜單,按數字順序排列的菜單項将顯示在标準輸出上。 select 預設使用提示字串3(Prompt String 3,$PS3, 即#?),但同樣可以被修改。 使用者輸入菜單清單中的某個數字,執行相應的指令 使用者輸入被儲存在内置變量 REPLY 中
選出一個最喜歡吃的蔬菜
上面這段代碼,會輸出如下的效果
如果省略了 <code>[in list]</code> 那麼 <code>select</code> 将會使用傳入腳本的指令行參數(<code>$@</code>)或者傳入函數的參數作為 list。可以與 <code>for variable [in list] </code>中 <code>in list</code> 被省略的情況做比較。 下面将省略 這個清單來實作上面的例子。 運作效果與上面的結果是一緻的。
循環,顧名思義就是重複性的執行某一基本操作。在Linux/Bash 中有三種基本循環,for,while,until循環。
for 循環 可以有以下的清單生成方式 直接給出清單
直接給出一個整數清單
能夠傳回清單的指令
使用glob 如 <code>*.sh</code> ,便是目前目錄下的.sh檔案清單
直接使用某個變量引用 如$@,$* ,或者某個變量
也可以直接周遊某個數組
檢查某些指定的檔案是否存在
Bash中的while循環結構與其他程式設計語言的while循環結構一緻的,在循環的開始就判斷條件是否滿足,如果循環條件為真,就繼續執行循環,如果為假則跳出循環。 其文法結構如下
CONDITION:循環控制條件;進入循環之前,先做一次判斷;每一次循環之後會再次做判斷;條件為“true”,則執行一次循環;直到條件測試狀态為“false”終止循環。 是以:CONDTION一般應該有循環控制變量;而此變量的值會在循環體不斷地被修正。 進入條件:CONDITION為true 退出條件:CONDITION為false while循環的括号結構不是必須存在的

示例:簡單的while循環

示例:多測試條件的while循環

一個 <code>while</code> 循環可以有多個測試條件,但隻有最後的那一個條件決定了循環是否終止。這是一種你需要注意到的不同于其他循環的文法。

示例:在 while 循環中結合 read 指令,我們就得到了一個非常易于使用的 while read 結構。它可以用來讀取和解析檔案 。

與while循環相反,until循環是其測試條件為真時,跳出循環。也就是說,測試條件為假,進入循環,測試條件為真退出循環。 而且,與其他程式設計語言不一樣的地方在于,until循環的測試條件在循環的頂部。 文法如下所示

示例:讀取使用者輸入,并輸出到标準輸出上,如果是end結束

break 和 continue 指令的作用和其他程式設計語言中的作用一樣。break 是跳出結束循環,continue是跳出本次循環,進入到下一次循環。 但是 ,在bash 中,break 和 continue 有一種特殊用法,能夠指定跳出其上 N 層的循環,也就是 continue [N]
接下來我們使用一個示例來演break和continue的使用。
用于将參量清單左移指定次數,預設是左移1次。  參量清單 list 一旦被移動,最左端的那個參數就從清單中删除。while 循環周遊位置參量清單時,常用到 shift。

示例:批量添加使用者,并能夠根據輸入的選項,進行不同的輸出

雙小括号方法,即<code>((…))</code>格式,也可以用于算術運算,雙小括号方法也可以使bash Shell實作C語言風格的變量操作。for循環和while循環都可以使用這種<code>((…))</code>格式
** for 循環 的文法格式如下 **
until循環的文法如下
while循環的文法如下
while 循環的特殊用法(周遊檔案的每一行)

在實際的使用過程中,可以實作多種循環的嵌套,以便實作複雜任務,應當具體情況具體分析。

如何在 for,while 和 until 之間做出選擇?我們知道在C語言中,在已知循環次數的情況下更加傾向于使用 for 循環。但是在Bash中情況可能更加複雜一些。Bash中的 for 循環相比起其他語言來說,結構更加松散,使用更加靈活。是以使用你認為最簡單的就好。

     本文轉自Eumenides_s 51CTO部落格,原文連結:http://blog.51cto.com/xiaoshuaigege/1965105,如需轉載請自行聯系原作者

繼續閱讀