Linux 伺服器系統管理第十三章 Shell Script 程式設計  上一頁    

13-7 函數

內容:

13-7-1 Shell 函數結構

Shell script 也具有『函數』(Function)的功能,但它的呼叫和宣告與一般程式語言(如 C 語言)稍有不同。第一個不同點是區域與整體變數之間的界限如何;第二個不同點是函數呼叫時,如何攜帶引數的問題。如能克服這兩個不同點,使用 Shell script 的函數呼叫就沒有什麼困難。函數有兩種定義方法,如下所示:

Function function_name

{

命令或程式區塊

……

}

function_name()

{

命令或程式區塊

……

}

Shell script 並沒有像 C 語言有函數宣告的敘述,因 Shell script 是直譯程式,它會直接編譯執行,不像一般程式語言需經過兩階段的編譯動作,才會產生可執行檔。因此,Shell script 的函數宣告必須在函數呼叫之前完成,否則便會找不到函數程式的位置,下列範例應可窺視出函數的宣告與呼叫方法。

A. 範例 ex7_27

此範例會先宣告一個函數名為 disp,它的功能是畫出一條直線,接著主程式再呼叫該函數;程式如下:$vi ex7_27

#! /bin/bash

# 1+2! + 3! +, ..., +k! = total

function disp

{

   echo "----------------------"

}

 

echo -n "A number of display line =>"

read k

while [ $k -gt 0 ]; do

   echo -n "$k  "

   disp

   k=`expr $k - 1 `

done

執行結果如下:

$ ex7_27

A number of display line =>4

4  ----------------------

3  ----------------------

2  ----------------------

1  ----------------------

13-7-2 區域變數與整體變數

一般的程式語言,其函數的程式實體都是獨立的記憶體空間,所宣告的變數一般稱之為區域變數(Local variable)。在巢狀函數(函數內再宣告函數)的情況下,父函數與子函數的區域變數是不會衝突的,除非使用者特意將某些父函數的變數宣告成整體變數(Global variable),父函數與子函數才可以共用這些變數,否則函數之間的變數是無關聯的。以上這些觀念與 Shell script 有點相反,Shell script 是除非有特殊聲明,否則所有的變數都是整體變數,且與 Shell 環境的特性有關。

Shell script 變數有環境變數、位置變數與自訂變數等三種類型,其中環境變數是系統產生並適用於任何函數,因此它必定是『整體』變數,至於位置變數會依照函數(無論子函數或命令程式)被呼叫時,攜帶引數的所在位置而定,並自動以 $1$2$3$n 表示之;函數若再呼叫其他函數,其位置也都使用相同的方式表示,因此位置變數一定是『區域』變數。至於自訂變數,除非特別指定為區域變數(local 命令),否則一律為『整體』變數。以下幾個範例用來說明函數變數的特性。

A. 範例 ex7_28

本範例說明函數之間的自訂變數與位置變數為整體性或區域性關係,程式如下:$vi ex7_28

#! /bin/bash

# 位置變數為區域性, 自訂變數為整體性

funct()

{

   echo " "

   echo "Inside function "

   echo "    funct: $# agrs: $1 $2 $3"   # $# $1 $2 $3 為區域變數

   var1="in function"                 # var1 為整體變數

   echo "    var1 = $var1"

}

 

echo "Outside function"

echo "    $0: $# args: $1 $2 $3"

var1="Out function"

echo "    var1 = $var1"

 

funct arg1 arg2 arg3

echo " "

echo "Outside function"

echo "    var1 = $var1"

主程式內產生一個整體變數 var1,它可以被主程式與 funct 函數共用,執行結果如下:

$ ex7_28 par1 par2

Outside function

   ./function2: 2 args: par1 par2

   var1 = Out function

 

Inside function

   funct: 3 agrs: arg1 arg2 arg3

   var1 = in function

 

Outside function

   var1 = in function

由執行結果可以看出,主程式與函數的位置變數都是以 $1$2$3 $# 表示,但他們之間的內容並不相同,因為他們都是區域變數的關係;另外 $0 為整體變數,僅表示主程式的命令(ex7_28)。至於主程式所產生的 var1 亦為整體變數,函數內將 var1 設定為其他內容之後,主程式內的 var1 也會跟著改變。

B. 範例 ex7_29

如果需要區域變數的話,可以在產生變數的標頭加上 local 命令即可,範例如下:$vi ex7_29

#! /bin/bash

# local 產生區域變數

funct()

{

   echo " "

   echo "Inside function "

   local var1="in function"

   echo "    var1 = $var1"

}

 

echo "Outside function"

var1="Out function"

echo "    var1 = $var1"

 

funct

echo " "

echo "Outside function"

echo "    var1 = $var1"

上述程式中,函數 funct() 內產生一個 var1 的區域變數,雖然它與主程式的var1 變數相同名稱,但所佔的記憶體空間不同。執行結果如下:

$ ex7_29

Outside function

   var1 = Out function

 

Inside function

   var1 = in function

 

Outside function

   var1 = Out function

主程式的 var1 內容與函數的 var1 並不相互衝突,這兩個變數是獨立的,他們只不過名稱相同罷了。

13-7-3 引數傳遞與傳回

在一般程式語言裡,呼叫函數常需要攜帶某些引數,來作為執行函數的輸入,而在函數執行完畢之後,也常會要求傳回某些執行的結果。簡單的說,這就是函數的輸入與輸出,當然 Shell script 函數也需要這些功能,但它的製作方式與其他語言略有不同。基本上,Shell script 並無法指定引數的資料型態,也無法利用 return 傳回數值,它可能會利用位置變數作為引數的輸入,或利用整體變數作為函數與主程式之間的資料交換;以下用兩個範例來說明傳遞方法。

A. 範例 ex7_30

此範例以位置變數($1)作為引數輸入,呼叫函數時,會在函數的後面加入一個引數(disp $count),亦即將該變數的內容傳遞給函數引用,程式如下:$vi ex7_30

#! /bin/bash

# argument($1) an input parameter

function disp

{

   t=$1

   while [ $t -gt 0 ]; do

      echo -n "*"

      t=`expr $t - 1`

   done

   echo " "

}

 

echo -n "A number of display line =>"

read k

count=0

while [ $count -le $k ]; do

   disp $count

   count=`expr $count + 1 `

done

執行結果如下:

$ ex7_30

A number of display line =>5

 

*

**

***

****

*****

B. 範例 ex7_31

針對函數回傳部份(即是函數執行後輸出),Shell script 大多將所欲回傳的數值存入整體變數內,主程式再從整體變數內取出,程式範例如下:$vi ex7_31

#! /bin/bash

# 1+2! + 3! +, ..., +k! = total

fun1()

{

   t=$1; sum=1

   while [ $t -gt 1 ]; do

       sum=`expr $sum \* $t`

       t=`expr $t - 1`

   done

   return $sum

}

 

echo -n "Please enter a number =>"

read k

sum=1; total=0; i=1

while [ $k -ge $i ]; do

   fun1 $i

   total=`expr $total + $sum `

   i=`expr $i + 1`

done

echo "1 + 2! +3! +, ...+ $k ! = $total"

執行結果如下:

$ ex7_31

Please enter a number =>7

1 + 2! +3! +, ...+ 7 ! = 5913

 

翻轉工作室:粘添壽

 

Linux 伺服器系統管理 - CentOS:

 

 

 

翻轉電子書系列: