說起函數調用,相信大家也不會陌生,然而對於初學Shell的我來說,Shell中函數調用方式卻有點讓我不太習慣,自己也走了不少的彎路,因為傳遞參數時出了一個很“自然”的錯誤,也讓我吃了不少的苦頭,所以總結一下Shell中函數的調用方法。一、Shell中函數的定義為了方便程式和管理和模組化並減少代碼的重複,函數的確是一個好東西。而Shell中函數的定義有兩種方法,如下:function fname(){statements;}或fname(){statements;}注意,()內是沒有參數的,它並不像C語言那樣,在()裡可以有參數。那大家可能就鬱悶了,函數調用或多或少總是會需要一些參數,那麼這些參數要怎麼傳遞進來呢?其實參數傳遞方式為:fname;(不需要傳遞參數)或fname agr1 arg2(需要傳遞兩個參數);二、自訂函數的例子不知道大家的情況如何,反正一開始我就覺得很彆扭,因為在C語言中,例如我定義一個函數int cmp(int a, int b),那麼我就會在函數中使用到函數頭中聲明的變數a和b,而在Shell中卻沒有定義參數,那我的函數又需要用到這兩個參數,怎麼辦好呢?下面就用一個例子來說明好了。
#! /bin/bash# Filename:LoopPrint.shfunction LoopPrint(){count=0;while [ $count -lt $1 ];doecho $count;let ++count;sleep 1;donereturn 0;}read -p "Please input the times of print you want: " n;LoopPrint $n;
先來說說這個程式的功能吧,就是輸入一個數字n,然後從0開始每隔1秒輸入一個數字,直到輸出n-1為止。首先,程式會要求你輸入一個數學,然後調用函數來進行輸出的功能。注意注釋1的那一句,裡面有一個變數$1,大家應該還記得調用函數時參數的傳遞方式,即fname agr1 arg2,這裡的$1就是表示第一個參數,依此類推,$2就是第二個參數,$3就是第3個參數,$n就是表示第n個參數。所以$1就是變數n的值。這樣說大家懂了吧!
補充一下,就是:$0:是指令碼本身的名字;$#:是傳給指令碼的參數個數;$@:是傳給指令碼的所有參數的列表,即被擴充為"$1" "$2" "$3"等;$*:是以一個單字串顯示所有向指令碼傳遞的參數,與位置變數不同,參數可超過9個,即被擴充成"$1c$2c$3",其中c是IFS的第一個字元;$$:是指令碼啟動並執行當前進程ID號;
$?:是顯示最後命令的退出狀態,0表示沒有錯誤,其他表示有錯誤;特別注意,傳遞參數時,(這個例子中)一定要寫成LoopPrint $n;而不能寫成LoopPrint n。為什嗎?例如你輸入的是20,則n的值($n)為20,前者表示的是把n的值,即20傳遞給函數LoopPrint,而後者則表示把字元n傳遞給函數LoopPrint。這點與在靜態語言中的函數參數傳遞是很不同的,因為在Shell中變數的使用並不需要先定義,所以要使用變數,讓Shell知道它是一個變數,並要傳遞它的值時,就是用$n,而不能直接用n,否則只把n當作一個字元來處理,而不是一個變數。三、範圍問題函數的範圍與C/C++語言中的作用約束是一樣的,函數的定義一定要出現在函數的調用語句之前,但是有一點跟C/C++中不一樣的就是變數的範圍問題,經過本人的實驗,在注釋1的語句改為while [ $count -lt $n ];也是可行的,即函數可以使用本檔案中出現的任何變數,但是本人還是建議使用上面例子中的方法,即while [ $count -lt
$1 ],並且不要隨意使用函數中的變數之外的變數,因為你並不一定知道你調用函數時函數外有什麼變數存在也不知道它的值是什麼,也不能保證別人在使用你的函數時會傳遞你在函數中使用到的變數名,如這裡的n,別人在使用時可能傳遞的就是他自己定義的變數,如Count等。