在小節中,我們將介紹bash函數的基礎知識以及它們在bash shell腳本中的工作方式。
bash腳本中的函數是重用代碼的絕佳選擇。Bash函數可以定義為一組命令,在bash腳本中多次調用。bash函數使腳本更具可讀性,並避免一次又一次地編寫相同的代碼。它還允許開發人員將複雜而冗長的代碼分解為小部分,可以在需要時調用它們。可以隨時重複調用函數,這樣就能夠重用,優化和最小化代碼。
以下是有關bash函數的一些要點:
- 在shell腳本中必須先聲明函數,然後才能使用它。
- 參數可以傳遞給函數,並在函數內部以
$1
,$2
,$n
等訪問。 - 在函數內分配局部變數,此變數的範圍僅是該特定函數。
- Bash shell中使用函數可以覆蓋內置命令。
1. 語法
bash聲明函數的語法有兩種格式定義:
第一種方法:以函數名稱開頭,後跟括弧。這是最優選且最常用的方法,語法如下:
function_name () {
commands
}
單行語法如下:
function_name () { commands; }
第二種方法:以函數保留字開頭,後跟函數名稱:
function function_name {
commands
}
單行語法如下:
function_name () { commands; }
與大多數編程語言相比,Bash函數有所限制。下麵通過一些示例來理解這個概念。
示例:方法1
#!/bin/bash
welcome () {
echo 'Welcome to zaixian.'
}
welcome
執行上面示例代碼,得到以下結果:
Welcome to zaixian.
示例:方法2
#!/bin/bash
function welcome () {
echo 'Welcome to zaixian.'
}
welcome
執行上面示例代碼,得到以下結果:
Welcome to zaixian.
2. 傳遞參數
像大多數編程語言一樣,還可以傳遞參數並在bash函數中處理數據。我們可以將數據插入函數中,就像將命令行參數傳遞給bash腳本一樣。
要將參數傳遞給bash函數,需要在函數名稱之後插入它們。在函數名稱和參數之間使用空格,在參數周圍使用雙引號以防止參數中帶有空格的參數解析錯誤也是一個不錯的選擇。
以下是有關將參數傳遞給bash函數的一些要點:
- 給定的參數以
$1
,$2
,$3
,...$n
的形式訪問,對應於函數名後參數的位置。 $0
變數的值是函數的名稱。$#
變數用於保存賦予函數的位置引數/參數的數量。$*
和$@
變數用於保存賦予函數的所有參數。- 當
$*
與雙引號(即"$*"
)一起使用時,它將擴展為一個由空格分隔的字串。例如,"$1 $2 $n"
等。 - 當
$@
與雙引號(即"$@"
)一起使用時,它將擴展為單獨的字串。例如,"$1" "$2" "$n"
等。 - 當
$*
和$#
不與雙引號一起使用時,它們都是相同的。
- 當
以下是說明如何將參數傳遞給函數以及如何訪問函數內部參數的過程的代碼。
Bash腳本
#!/bin/bash
#Script to pass and access arguments
function_arguments(){
echo $1
echo $2
echo $3
echo $4
echo $5
}
#Calling function_arguments
function_arguments "We" "welcome" "you" "on" "zaixian"
執行上面示例代碼,得到以下結果:
在此腳本中,在調用function_arguments
函數之後添加了值:"We"
"welcome"
"you"
"on"
"zaixian"
。這些值將作為參數傳遞到function_arguments
並存儲在局部變數中。但是,與其他語言不同,解釋器將傳遞的值存儲到預定義的變數中,然後根據傳遞的參數順序進行命名。
例如,
"We"
存儲在變數$1
中。"welcome"
存儲在變數$3
中。"you"
存儲在變數$3
中。"on"
存儲到變數$4
中。"zaixian"
存儲在變數$5
中。
3. 變數的作用域
全局變數定義為可以在腳本內的任意位置訪問的變數,而不管它的範圍如何。默認情況下,所有變數都定義為全局變數,即使它們在函數內部聲明也是如此。還可以將變數創建為局部變數。可以使用local
關鍵字在函數體內聲明局部變數。首次分配關鍵字時。它們只能在該函數內部訪問。可以在不同的函數中創建具有相同名稱的局部變數。要添加局部變數,使用以下語法:
local var_name=<var_value>
為了更好地理解變數作用域如何在Bash腳本中工作,請查看以下示例:
Bash腳本
#!/bin/bash
v1='A'
v2='B'
my_var () {
local v1='C'
v2='D'
echo "Inside Function"
echo "v1 is $v1."
echo "v2 is $v2."
}
echo "Before Executing the Function"
echo "v1 is $v1."
echo "v2 is $v2."
my_var
echo "After Executing the Function"
echo "v1 is $v1."
echo "v2 is $v2."
執行上面示例代碼,得到以下結果:
在上面輸出中,如果在函數體內設置與全局變數同名的局部變數,則它將優先於全局變數(即,局部變數覆蓋全局變數)。可以在函數內修改全局變數。
4. 返回值
大多數編程語言都具有函數返回值的概念。函數可以將數據發送回原始調用位置。與“真實”編程語言中的函數不同,Bash函數不提供在調用時返回值的支持。但是,它們允許設置返回狀態,這種狀態類似於程式或命令如何以退出狀態退出。bash函數完成時,其返回值是函數中最後執行的語句的狀態。對於成功狀態,它將返回0
,對於失敗,將返回1-255
範圍內的非零十進位數。
可以使用關鍵字return
指示返回狀態,並將它分配給變數$?
。return
語句終止函數並用作函數的退出狀態。
例如,參考以下代碼:
#!/bin/bash
#Setting up a return status for a function
print_it () {
echo Hello $1
return 5
}
print_it User
print_it Reader
echo The previous function returned a value of $?
執行上面示例代碼,得到以下結果:
從函數返回值的另一個更好的選擇是使用echo
或printf
命令將列印值發送到stdout
,如下腳本代碼所示:
#!/bin/bash
print_it () {
local my_greet="Welcome to zaixian."
echo "$my_greet"
}
my_greet="$(print_it)"
echo $my_greet
5. 覆蓋命令
可以通過創建與要覆蓋的命令同名的函數來覆蓋bash命令。例如,如果想覆蓋echo
命令,那麼只需要創建一個名稱為echo
的函數即可。
覆蓋bash命令的概念在某些情況下可能會很有用,例如當要使用帶有特定選項的命令時,或者當我們不喜歡在腳本中多次為整個命令提供選項時。在這種情況下,可以將內置bash命令覆蓋為帶選項的命令。下麵通過一些示例來瞭解在Bash Shell腳本中覆蓋命令:
示例
在此示例中,我們將覆蓋echo
命令,並將時間戳以參數的形式添加到了echo
命令中。
Bash腳本
#!/bin/bash
#Script to override command using function
echo () {
builtin echo -n `date +"[%m-%d %H:%M:%S]"` ": "
builtin echo $1
}
echo "Welcome to zaixian."
總結
在本小節中,我們演示了有關Bash函數的使用和技巧。Bash函數是一個開發用於執行特定操作的可重用代碼塊。定義後可以在腳本中多次調用它。