參數的調用方法
在其他語言中,函數參數分為形參和實參,其中,形參是函數定義時就指定的參數;而實參是函數被調用時才指定的參數(通常放在括號里,參數之間用逗號隔開)
shell的函數參數比較特殊,實際上shell將腳本的參數和函數的參數統一處理,怎么調用腳本參數就怎么調用函數參數。
function_name arg arg1 arg2 ...
function_name是函數名,arg表示函數參數,通過空格隔開。
通過位置變量接受函數參數
和shell腳本相同,shell函數通過系統變量獲取參數值。
從命令行傳遞給shell函數的參數叫做位置參數,shell會根據參數的位置來接受對應的值。
在shell內部,用戶可以通過一系列的系統變量來獲取參數,這些變量的名稱都是固定的,非常簡單,只用一個字符表示,例如$0表示腳本名稱;$1表示傳遞的第一個參數......
常用於參數傳遞的系統變量
變量 | 說明 |
---|---|
$n | n是一個參數,從1開始表示參數的位置,例如:$1表示第一個參數,$2表示第二個參數 |
$# | 命令行參數的個數 |
$0 | 當前shell腳本的名稱 |
$? | 前一個命令或者是函數的返回狀態碼,0代表執行成功,非0即失敗 |
$* | 以”參數1參數2....“的形式將所有函數通過一個字符串返回 |
$@ | 以”參數1“”參數2“....的形式返回每個參數 |
$_ | 保存之前執行的命令的最后的一個參數 |
舉個簡單的例子:
#!/bin/bash
func ()
{
echo "這是第 $2 個參數"
echo "這是第 $4 個參數"
echo "這是第 $1 個參數"
}
func 1 2 3 4
輸出結果為:
shift移動位置參數
shift命令可以使位置參數向左移。比如shift 3表示位置參數$4 向左移動三變成 $1,原來的$5現在變成$2,而原來的$1、$2、$3丟棄,** 因為$0是腳本名嘛!**。不帶參數的shift命令相當於shift 1。
我們知道,對於位置變量或命令行參數,其個數必須是確定的,或者當 Shell 程序不知道其個數時,可以把所有參數一起賦值給變量$*。若要求 Shell 在不清楚位置變量個數的情況下,依次遍歷每個參數然后進行相應處理。
例如:
#!/bin/bash
func ()
{
while [ $# -ne 0 ]
do
echo "第一個參數為:$1 ,一共有$# 個參數"
shift
done
}
func 1 2 3 4 5 6
用祖傳畫圖來嘗試畫個示意圖
-
Shift 命令還有另外一個重要用途, Bsh 定義了9個位置變量,從 $1 到 $9,這並不意味着用戶在命令行只能使用9個參數,借助 shift 命令可以訪問多於9個的參數。
-
Shift 命令一次移動參數的個數由其所帶的參數指定。例如當 shell 程序處理完前九個命令行參數后,可以使用 shift 9 命令把 $10 移到 $1。
-
shift會影響系統變量$#的值 _
通過getopts接收函數參數
所有學習Unix或Linux的人,都會記得這樣一句話:命令+參數+選項;例如ls -l,這個“ -l ”也是個參數,只不過這個參數有一個前導的連字符。
通過上面的步驟已經可以通過$1,$2...獲取全部參數,還可以通過$#來獲取參數的個數;但是我們的腳本程序不會這么簡單,一個參數往往有很多的值,根據參數的值執行不同的操作,這時就會用到一種技術——參數拓展
getopts是bash內嵌的一個命令。通過該命令可以獲得函數的選項和參數值或者是腳本的命令行選項和參數值。語法為:
getopts optstring [args]
optstring包含一個被getopts識別的選項名稱列表。如果某個選項后面跟着一個冒號,表示可以為該選項提供參數值。同時參數值將被保存到一個名稱為$OPTARG的系統變量中。getopts遍歷每個選項,將選項名保存到args變量中。
#!/bin/bash
func ()
{
while getopts "a:b:c:" arg
do
case "$arg" in
a)
echo "-a表示all全部。。。參數值為; $OPTARG"
;;
b)
echo "-b表示返回。。。參數值為: $OPTARG"
;;
c)
echo "-c還沒想好。。。參數值為:$OPTARG"
;;
?)
echo "沒有找到這條命令。。。。"
exit 1
;;
esac
done
}
func -a "你好" -b "hello" -c "ARE YOU OK?"
輸出結果為:
間接參數傳遞
所謂間接參數傳遞,就是指通過間接變量引用來實現函數參數的傳遞。
一個變量的值是另一個變量的變量名,則該變量就可以說是間接變量
例如:
var=work
work=job
此時引用變量work就可以用:
${!var}
舉個簡單的示例:
#!/bin/bash
func ()
{
echo "$1"
}
var=work #定義變量var的變量值為work
work=job #定義變量work的變量值為job
func $var #將$var作為函數參數
func $work #直接引用$work作為函數參數
func ${!var} #使用間接參數傳遞的方式調用$work的值
work=test #重新定義變量work的值為test
func $var
func ${!var} #再次傳遞參數試試
輸出結果為:
全局變量傳遞
原理很簡單,就是通過全局變量的替換來實現參數傳遞(不建議這樣寫,因為過段時間可能就只有上帝才能看懂這段代碼)
定義一個函數判讀文件是否存在
#!/bin/bash
file="/bin"
func ()
{
if [ -a "$file" ];then
echo "文件存在"
else
echo "文件不存在"
fi
}
func
file="/asdawdaasf"
func
輸出結果為:
數組傳遞參數
將整個數組作為參數傳遞給函數(將數組中的元素展開,看成是由空格隔開的參數傳遞給函數)
例如:
#!/bin/bash
array=(a b c d e "f g" )
func ()
{
echo "參數個數為: $# "
while [ $# -gt 0 ]
do
echo $1
shift
done
}
func "${array[@]}"
輸出結果為