Linux的shell程式設計(三)(轉)

azz發表於2007-08-25
Linux的shell程式設計(三)(轉)[@more@]  接下來以bash為例向大家介紹shell程式設計的高階部分:shell程式設計的流程控制、除錯方法及shell程式的執行方法,順便也向大家介紹一下bash的內部命令。

  四、shell程式設計的流程控制

  和其他高階程式設計語言一樣,shell提供了用來控制程式執行流程的命令,包括條件分支和迴圈結構,使用者可以用這些命令建立非常複雜的程式。

  與傳統的語言不同的是,shell用於指定條件值的不是布林表示式而是命令和字串。

  1.test測試命令

  test命令用於檢查某個條件是否成立,它可以進行數值、字元和檔案三個方面的測試,其測試符和相應的功能分別如下:

  (1)數值測試:

  -eq:等於則為真

  -ne:不等於則為真

  -gt:大於則為真

  -ge:大於等於則為真

  -lt:小於則為真

  -le:小於等於則為真

  (2)字串測試:

  =:等於則為真

  !=:不相等則為真

  -z字串:字串長度偽則為真

  -n字串:字串長度不偽則為真

  (3)檔案測試:

  -e檔名:如果檔案存在則為真

  -r檔名:如果檔案存在且可讀則為真

  -w檔名:如果檔案存在且可寫則為真

  -x檔名:如果檔案存在且可執行則為真

  -s檔名:如果檔案存在且至少有一個字元則為真

  -d檔名:如果檔案存在且為目錄則為真

  -f檔名:如果檔案存在且為普通檔案則為真

  -c檔名:如果檔案存在且為字元型特殊檔案則為真

  -b檔名:如果檔案存在且為塊特殊檔案則為真

  另外,Linux還提供了與(“!”)、或(“-o)、非(“-a”)三個邏輯運算子用於將測試條件連線起來,其優先順序為:“!”最高,“-a”次之,“-o”最低。

  同時,bash也能完成簡單的算術運算,格式如下:

  $[expression]

  例如:var1=2

  var2=$[var1*10+1]

  則:var2的值為21。

  2.if條件語句

  shell程式中的條件分支是透過if條件語句來實現的,其一般格式為:

  if條件命令串

  then

  條件為真時的命令串

  else

  條件為假時的命令串

  fi

  3.for迴圈

  for迴圈對一個變數的可能的值都執行一個命令序列。賦給變數的幾個數值既可以在程式內以數值列表的形式提供,也可以在程式以外以位置引數的形式提供。for迴圈的一般格式為:

  for變數名

  [in數值列表]

  do

  若干個命令列

  done

  變數名可以是使用者選擇的任何字串,如果變數名是var,則在in之後給出的數值將順序替換迴圈命令列表中的$var。如果省略了in,則變數var的取值將是位置引數。對變數的每一個可能的賦值都將執行do和done之間的命令列表。

  4.while和until迴圈

  while和until命令都是用命令的返回狀態值來控制迴圈的。While迴圈的一般格式為:

  while

  若干個命令列1

  do

  若干個命令列2

  done

  只要while的“若干個命令列1”中最後一個命令的返回狀態為真,while迴圈就繼續執行do...done之間的“若干個命令列2”。

  until命令是另一種迴圈結構,它和while命令相似,其格式如下:

  until

  若干個命令列1

  do

  若干個命令列2

  done

  until迴圈和while迴圈的區別在於:while迴圈在條件為真時繼續執行迴圈,而until則是在條件為假時繼續執行迴圈。

  Shell還提供了true和false兩條命令用於建立無限迴圈結構的需要,它們的返回狀態分別是總為0或總為非0

  5.case條件選擇

  if條件語句用於在兩個選項中選定一項,而case條件選擇為使用者提供了根據字串或變數的值從多個選項中選擇一項的方法,其格式如下:

  case string in

  exp-1)

  若干個命令列1

  ;;

  exp-2)

  若干個命令列2

  ;;

  ……

  *)

  其他命令列

  esac

  shell透過計算字串string的值,將其結果依次和表示式exp-1、exp-2等進行比較,直到找到一個匹配的表示式為止,如果找到了匹配項則執行它下面的命令直到遇到一對分號(;;)為止。

  在case表示式中也可以使用shell的萬用字元(“*”、“?”、“[ ]”)。通常用“*”作為case命令的最後表示式以便使在前面找不到任何相應的匹配項時執行“其他命令列”的命令。

  6.無條件控制語句break和continue

  break用於立即終止當前迴圈的執行,而contiune用於不執行迴圈中後面的語句而立即開始下一個迴圈的執行。這兩個語句只有放在do和done之間才有效。

  7.函式定義

  在shell中還可以定義函式。函式實際上也是由若干條shell命令組成的,因此它與shell程式形式上是相似的,不同的是它不是一個單獨的程式,而是shell程式的一部分。函式定義的基本格式為:

  functionname

  {

  若干命令列

  }

  呼叫函式的格式為:

  functionname param1 param2……

  shell函式可以完成某些例行的工作,而且還可以有自己的退出狀態,因此函式也可以作為if、while等控制結構的條件。

  在函式定義時不用帶引數說明,但在呼叫函式時可以帶有引數,此時shell將把這些引數分別賦予相應的位置引數$1、$2、...及$*。

  8.命令分組

  在shell中有兩種命令分組的方法:“()”和“{}”,前者當shell執行()中的命令時將再建立一個新的子程式,然後這個子程式去執行圓括弧中的命令。當使用者在執行某個命令時不想讓命令執行時對狀態集合(如位置引數、環境變數、當前工作目錄等)的改變影響到下面語句的執行時,就應該把這些命令放在圓括弧中,這樣就能保證所有的改變只對子程式產生影響,而父程式不受任何干擾;{}用於將順序執行的命令的輸出結果用於另一個命令的輸入(管道方式)。當我們要真正使用圓括弧和花括弧時(如計算表示式的優先順序),則需要在其前面加上轉義符()以便讓shell知道它們不是用於命令執行的控制所用。

  9.訊號

  trap命令用於在shell程式中捕捉到訊號,之後可以有三種反應方式:

  (1)執行一段程式來處理這一訊號

  (2)接受訊號的預設操作

  (3)忽視這一訊號

  trap對上面三種方式提供了三種基本形式:

  第一種形式的trap命令在shell接收到signal list清單中數值相同的訊號時,將執行雙引號中的命令串。

  trap 'commands' signal-list

  trap "commands" signal-list

  為了恢復訊號的預設操作,使用第二種形式的trap命令:

  trap signal-list

  第三種形式的trap命令允許忽視訊號:

  trap " " signal-list

  注意:

  (1)對訊號11(段違例)不能捕捉,因為shell本身需要捕捉該訊號去進行記憶體的轉儲。

  (2)在trap中可以定義對訊號0的處理(實際上沒有這個訊號),shell程式在其終止(如執行exit語句)時發出該訊號。

  (3)在捕捉到signal-list中指定的訊號並執行完相應的命令之後,如果這些命令沒有將shell程式終止的話,shell程式將繼續執行收到訊號時所執行的命令後面的命令,這樣將很容易導致shell程式無法終止。

  另外,在trap語句中,單引號和雙引號是不同的,當shell程式第一次碰到trap語句時,將把commands中的命令掃描一遍。此時若commands是用單引號括起來的話,那麼shell不會對commands中的變數和命令進行替換,否則commands中的變數和命令將用當時具體的值來替換。

  五、執行shell程式的方法

  使用者可以用任何編輯程式來編寫shell程式。因為shell程式是解釋執行的,所以不需要編譯裝配成目標程式,按照shell程式設計的慣例,以bash為例,程式的第一行一般為“#!/bin/bash”,其中#表示該行是註釋,歎號“!”告訴shell執行歎號之後的命令並用檔案的其餘部分作為輸入,也就是執行/bin/bash並讓/bin/bash去執行shell程式的內容。

  執行shell程式的方法有三種:

  (1)sh shell程式檔名

  這種方法的命令格式為:

  bash shell程式檔名

  這實際上是呼叫一個新的bash命令解釋程式,而把shell程式檔名作為引數傳遞給它。新啟動的shell將去讀指定的檔案,執行檔案中列出的命令,當所有的命令都執行完結束。該方法的優點是可以利用shell除錯功能。

  (2)sh

  格式為:

  bash

  這種方式就是利用輸入重定向,使shell命令解釋程式的輸入取自指定的程式檔案。

  (3)用chmod命令使shell程式成為可執行的

  一個檔案能否執行取決於該檔案的內容本身可執行且該檔案具有執行權。對於shell程式,當用編輯器生成一個檔案時,系統賦予的許可許可權都是644(rw-r-r--),因此,當使用者需要執行這個檔案時,只需要直接鍵入檔名即可。

  在這三種執行shell程式的方法中,最好按下面的方式選擇:當剛建立一個shell程式,對它的正確性還沒有把握時,應當使用第一種方式進行除錯。當一個shell程式已經除錯好時,應使用第三種方式把它固定下來,以後只要鍵入相應的檔名即可,並可被另一個程式所呼叫。

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10901326/viewspace-965898/,如需轉載,請註明出處,否則將追究法律責任。

相關文章