在 Bash shell 腳本中,函數是一種對一組指令進行分組以獲得特定結果的方法。函數可以被認為是迷你腳本。在某些編程語言中,函數也稱為過程和方法。函數是實現模塊化和可重用性的好方法。
本文介紹如何在 Linux 上使用函數 bash 腳本和示例。在本文結束時,您應該對使用 bash 的功能感到滿意。
內容
如何在 Bash 中定義函數
使用函數時需要了解兩件重要的事情。
- 定義一個函數,
- 調用一個函數。
與編寫和運行 bash 腳本的方式類似,您需要定義一個函數並調用它來運行該函數。
在 bash 中定義函數有兩種語法方式。第一種方法是通過 bash 內置關鍵字。 "function"
後跟函數名。代碼塊寫在裡面 大括號 {}
.
function [name] {
Block of code
}
第二種方法是創建沒有關鍵字的函數 "function"
. 以函數名開頭,後跟括號。
[name](){
Block of Code
}
你選擇哪個?好吧,這始終是個人選擇。選擇其中之一沒有缺點。
您還可以編寫一個被調用的單行函數。 緊湊的功能. 在一個緊湊的函數中用於花括號內的每一行代碼 分號 (;
).
啟動終端並編寫多行函數。如果現在按向上箭頭鍵,您會看到多行描述已轉換為緊湊函數。
[name](){ first_line; second_line; }
最佳實踐:
- 選擇一種語法並嘗試保持一致。
- 在協作環境中工作時,每個人在編碼時都保持相同的標準很重要。
命名約定
當你創建一個函數時,你必須給它一個名字。函數名稱應具有描述性,並避免其他函數、變量、常量等已使用的名稱。 《蛇案》 這是命名函數的推薦方法。對於蛇,單詞用下劃線分隔。
請參見下面的示例。我創建了一個名為 "hello_world"
在蛇形案例風格中,它只是將 hello world 打印到標準輸出(終端)。
hello_world() {
echo "Running Simple Hello World Function"
}
hello_world
如何在 Bash 中調用函數
讓我們創建一個簡單的清理函數,稱為 "log_cleanup"
這個函數的目的是 ".log"
超過 30 天的文件。
log_cleanup(){ echo "Running Cleanup On Older Logs - 30 days" find /home/karthick/Documents/Projects/logs/ -name "*.log" -type f -mtime +30 -delete echo "Cleanup Completed" }
定義了函數,但這足以讓函數完成其工作嗎?絕對不是。您必須為要運行的函數調用該函數。
要調用函數,請在函數定義後輸入函數名稱。
#!/usr/bin/env bash #### FUNCTION DEFINITION #### log_cleanup(){ echo "Running Cleanup On Older Logs - 30 days" find /home/karthick/Documents/Projects/logs -name "*.log" -type f -mtime +30 -delete echo "Cleanup Completed" } # Calling the function log_cleanup
如果我在定義之前嘗試調用該函數,則會收到以下錯誤:
line 3: log_cleanup: command not found

為什麼會這樣?運行腳本時,代碼會從上到下逐行解釋。讀取函數並將其加載到 bash 環境(內存)中。但是在這裡,您在解釋器讀取該函數並將其加載到環境中之前調用該函數。
當從另一個函數中調用一個函數時,函數定義可以是除第一個函數之外的任何順序。見下圖。功能 特色二 叫 特色一 什麼時候 特色三 叫 特色二 在他們的定義之前。然而 特色一 先定義它,然後調用它。到……的時候 特色一 任何被調用的函數定義都會被解釋並加載到環境中。

退出狀態和返回值
所有 Linux 命令都返回退出狀態 (0-255)。零被認為是成功,其餘的退出代碼被認為是具有各種含義的失敗。同樣,執行一個函數也會返回在該函數中執行的最後一個命令的退出狀態。
讓我再次運行相同的“乾淨”功能。但是我給出的路徑在我的機器上不可用,所以 find
命令失敗。我在用 $?
如圖所示,在腳本中獲取退出狀態。
Running Cleanup On Older Logs - 30 days find: '/home/karthick/Documents/Projectss/logs': No such file or directory Cleanup Completed Exit status of function log_cleanup is ⇒ 0

函數返回的退出狀態為 echo
該命令作為函數內的最後一個命令執行。這不是預期的行為。
要克服這種行為,您可以使用 bash 內置。 "return"
陳述。
$ type -a return
return is a shell builtin
return 接受一個整數 [N] 獲取值,退出函數,並將返回值提供給調用者(函數)。 在使用 return 語句之前,你應該了解一些關於如何使用 return 語句的規則。如前所述,return 接受 0 到 255 之間的整數值。如果沒有傳遞參數(整數值)或值大於 255,則 return 語句使用最後執行的命令的退出狀態。
請讓我通過退貨來修復它 "cleanup"
功能行為。在這裡,我們使用帶有 return 命令的條件語句。
#!/usr/bin/env bash #### FUNCTION DEFINITION #### log_cleanup(){ echo "[ INFO ] - Running Cleanup On Older Logs - 30 days" if [[ -d "/home/karthick/Documents/Projectss/logs" ]] then find -name "*.log" -type f -mtime +30 -delete echo "[ SUCCESS] - Cleanup Completed" else echo "[ ERROR ] - Directory path wrong... Cleanup has not happened..." return 1 fi } # Calling the function log_cleanup echo "++ Exit status of log_cleanup function is ==> $?"
請參閱下面的輸出。返回函數 退出代碼 1 從返回語句。
[ INFO ] - Running Cleanup On Older Logs - 30 days
[ ERROR ] - Directory path wrong… Cleanup has not happened…
++ Exit status of log_cleanup function is ==> 1

將參數傳遞給函數
就像向 bash 腳本傳遞參數一樣,函數也接受參數。令人困惑的部分是函數使用相同的 $1
…$9
訪問參數特殊變量。這與將參數傳遞給腳本相同。我需要了解當我在函數內部或外部使用這個特殊變量時會發生什麼。
cat > arg_test.sh #!/bin/bash echo "Value passed in $1 is = $1" howdy(){ echo "value of $1 inside function is = $1" } howdy # Function Call
複製上面的代碼片段並運行它以查看差異。細繩 "Howdy"
作為第一個參數傳遞給腳本。
$ ./arg_test.sh howdy
Value passed in $1 is = howdy
value of $1 inside function is =
從輸出中我們可以看到: $1
由於函數內部輸出空值, $1
函數內部是 $1
它們共享相同的名稱,但在功能之外。
要將參數傳遞給函數,請在函數名稱後留一個空格並傳遞參數,如下圖所示。每個空格分隔的參數都分配給自己的變量 $1
…$N
您可以在函數內部使用此變量來處理參數。
log_cleanup $1 $2 ….. $N

正如您在上面的屏幕截圖中看到的,我將目錄名稱和天數作為參數傳遞。
函數變量範圍
一旦在函數內部或外部創建變量,就可以全局訪問它。默認情況下,變量是在全局範圍內創建的。
請參見下面的示例。 當我嘗試訪問這兩個變量時, outside_function
什麼時候 inside_function
,您可以訪問這些值。這意味著即使函數已執行並退出,在函數中創建的變量也可以全局訪問。
#!/bin/bash outside_function="This variable is from outside the function" func1(){ inside_function="This variable is from inside the func1" } func1 echo $outside_function echo $inside_function

在某些編程語言中,這可能不起作用。函數內創建的變量在函數運行時可用。但是在 bash 中它的工作方式不同。
要使變量成為函數的局部變量,您可以使用 bash 內置函數。 "local"
關鍵詞。 local 關鍵字將變量的範圍從全局限制為局部,只允許在函數運行時訪問該變量。
#!/bin/bash
outside_function="This variable is from outside the function"
func1(){
local inside_function="This variable is from inside the func1"
}
func1
echo $outside_function
echo $inside_function

推薦閱讀:
- Bash 腳本 – 用示例解釋變量
local 關鍵字允許您在不同的函數中使用相同的變量名。

筆記: 您應始終避免使用已用作變量、函數和 bash 的 bash 關鍵字。上面的例子是為了理解它是如何工作的。
模塊化和可重用性
理解和寫作功能立即可用。但是需要時間來更好地了解您的環境以創建出色的功能。正如在介紹部分中已經指出的那樣,bash 的特性允許很好的模塊化和可重用性。
讓我們看一個例子。 創建了 20 個腳本。每個腳本包含: log_cleanup
執行我們在上一節中看到的內務管理任務的函數。 您可以創建一個函數定義並將其導入到 20 個腳本中,而不是在所有 20 個腳本中包含該函數。通過這種方式,我們實現了模塊化和可重用的功能。這是相似的 進口 Python中的語句, 包括 諸如 C 之類的語句
見下圖。我創建了兩個腳本。 script1.sh
什麼時候 script2.sh
什麼時候 log_cleanup
這些函數寫在一個名為 cleanup.sh
.

通過運行導入函數 source
命令。這個 source
此命令將運行作為參數傳遞的文件並將任何變量或函數加載到當前 bash 會話中。所以當你跑步時 log_cleanup
從另一個腳本文件中,函數被加載到當前環境中並且可以訪問。

從上圖中,您可以看到參數如何提供幫助。只有一個函數定義。根據您的用例,您可以修改函數以接受不同的參數和不同的腳本。
筆記: 您還可以運行 shell 腳本 source
此命令將在當前 shell 中運行腳本,而不是創建子 shell 來運行腳本。
結論是
本指南提供了 Bash 函數的示例以及如何在腳本中定義和調用它們。要熟悉函數,您需要使用不同的用例來練習它們。如果您有任何問題或意見,請隨時在下面的評論部分告訴我們。
相關文件:
- Bash 腳本 – 用示例解釋 For 循環
- Bash 腳本 – 用示例解釋 while 和 until 循環
- 定義帶和不帶導出的 Bash 變量之間的差異
- 使用 Linux 示例演示 Bash Echo 命令
- 面向初學者的 Bash Heredoc 教程
- 用示例解釋 Bash 重定向
BASHBash 函數Bash 腳本Bash 提示CLI 命令行Linux 腳本Shell 腳本