Bash 腳本 – 用示例解釋函數


在 Bash shell 腳本中,函數是一種對一組指令進行分組以獲得特定結果的方法。函數可以被認為是迷你腳本。在某些編程語言中,函數也稱為過程和方法。函數是實現模塊化和可重用性的好方法。

本文介紹如何在 Linux 上使用函數 bash 腳本和示例。在本文結束時,您應該對使用 bash 的功能感到滿意。

內容

  1. 如何在 Bash 中定義函數
  2. 命名約定
  3. 如何在 Bash 中調用函數
  4. 退出狀態和返回值
  5. 將參數傳遞給函數
  6. 函數變量範圍
  7. 模塊化和可重用性
  8. 結論是

如何在 Bash 中定義函數

使用函數時需要了解兩件重要的事情。

  • 定義一個函數,
  • 調用一個函數。

與編寫和運行 bash 腳本的方式類似,您需要定義一個函數並調用它來運行該函數。

在 bash 中定義函數有兩種語法方式。第一種方法是通過 bash 內置關鍵字。 "function" 後跟函數名。代碼塊寫在裡面 大括號 {}.

function [name] {
Block of code
}

第二種方法是創建沒有關鍵字的函數 "function". 以函數名開頭,後跟括號。

[name](){
Block of Code
}

你選擇哪個?好吧,這始終是個人選擇。選擇其中之一沒有缺點。

您還可以編寫一個被調用的單行函數。 緊湊的功能. 在一個緊湊的函數中用於花括號內的每一行代碼 分號 (;).

啟動終端並編寫多行函數。如果現在按向上箭頭鍵,您會看到多行描述已轉換為緊湊函數。

[name](){ first_line; second_line; }
緊湊的功能

最佳實踐:

  1. 選擇一種語法並嘗試保持一致。
  2. 在協作環境中工作時,每個人在編碼時都保持相同的標準很重要。

命名約定

當你創建一個函數時,你必須給它一個名字。函數名稱應具有描述性,並避免其他函數、變量、常量等已使用的名稱。 《蛇案》 這是命名函數的推薦方法。對於蛇,單詞用下劃線分隔。

請參見下面的示例。我創建了一個名為 "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  
在 Bash 中調用函數

如果我在定義之前嘗試調用該函數,則會收到以下錯誤:

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
使用 local 關鍵字的局部變量使用 local 關鍵字的局部變量

推薦閱讀:

  • 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 腳本