在 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 Script-For 循環
- Bash Scripting-while循環在示例中說明
- 帶和不帶導出的 Bash 變量定義的差異
- 使用 Linux 示例對 Bash echo 命令的說明
- 初學者的 Bash Here 文檔教程
- 使用示例描述的 Bash 重定向
BASHBash 函數Bash 腳本Bash 提示CLI命令行LinuxScriptingShell 腳本