提及函數調用,相信你們也不會陌生,然而對於初學Shell的我來講,Shell中函數調用方式卻有點讓我不太習慣,本身也走了很多的彎路,由於傳遞參數時出了一個很「天然」的錯誤,也讓我吃了很多的苦頭,因此總結一下Shell中函數的調用方法。bash
1、Shell中函數的定義模塊化
爲了方便程序和管理和模塊化並減小代碼的重複,函數的確是一個好東西。而Shell中函數的定義有兩種方法,以下:函數
function fname()oop
{spa
statements;進程
}作用域
或字符串
fname()input
{數學
statements;
}
注意,()內是沒有參數的,它並不像C語言那樣,在()裏能夠有參數。
那你們可能就鬱悶了,函數調用或多或少老是會須要一些參數,那麼這些參數要怎麼傳遞進來呢?其實參數傳遞方式爲:fname;(不須要傳遞參數)或fname agr1 arg2(須要傳遞兩個參數);
2、自定義函數的例子
不知道你們的狀況如何,反正一開始我就以爲很彆扭,由於在C語言中,例如我定義一個函數int cmp(int a, int b),那麼我就會在函數中使用到函數頭中聲明的變量a和b,而在Shell中卻沒有定義參數,那個人函數又須要用到這兩個參數,怎麼辦好呢?下面就用一個例子來講明好了。
#! /bin/bash
# Filename:LoopPrint.sh
function LoopPrint()
{
count=0;
while [ $count -lt $1 ];
do
echo $count;
let ++count;
sleep 1;
done
return 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看成一個字符來處理,而不是一個變量。
3、做用域問題
函數的做用域與C/C++語言中的做用約束是同樣的,函數的定義必定要出如今函數的調用語句以前,可是有一點跟C/C++中不同的就是變量的做用域問題,通過本人的試驗,在註釋1的語句改成while [ $count -lt $n ];也是可行的,即函數可使用本文件中出現的任何變量,可是本人仍是建議使用上面例子中的方法,即while [ $count -lt $1 ],而且不要隨意使用函數中的變量以外的變量,由於你並不必定知道你調用函數時函數外有什麼變量存在也不知道它的值是什麼,也不能保證別人在使用你的函數時會傳遞你在函數中使用到的變量名,如這裏的n,別人在使用時可能傳遞的就是他本身定義的變量,如Count等。