Bash函式


在小節中,我們將介紹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 Yiibai.'  
}  

welcome

執行上面範例程式碼,得到以下結果:

Welcome to Yiibai.

範例:方法2

#!/bin/bash  

function welcome () {  
    echo 'Welcome to Yiibai.'  
}  

welcome

執行上面範例程式碼,得到以下結果:

Welcome to Yiibai.

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" "Yiibai"

執行上面範例程式碼,得到以下結果:

在此指令碼中,在呼叫function_arguments函式之後新增了值:"We" "welcome" "you" "on" "Yiibai"。這些值將作為引數傳遞到function_arguments並儲存在區域性變數中。但是,與其他語言不同,直譯器將傳遞的值儲存到預定義的變數中,然後根據傳遞的引數順序進行命名。

例如,

  • "We"儲存在變數$1中。
  • "welcome"儲存在變數$3中。
  • "you"儲存在變數$3中。
  • "on"儲存到變數$4中。
  • "Yiibai"儲存在變數$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 $?

執行上面範例程式碼,得到以下結果:

從函式返回值的另一個更好的選擇是使用echoprintf命令將列印值傳送到stdout,如下指令碼程式碼所示:

#!/bin/bash  

print_it () {  
    local my_greet="Welcome to Yiibai."  
    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 Yiibai."

總結

在本小節中,我們演示了有關Bash函式的使用和技巧。Bash函式是一個開發用於執行特定操作的可重用程式碼塊。定義後可以在指令碼中多次呼叫它。