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
}

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

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

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

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

最佳實踐:

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

命名約定

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

請參見下面的示例。我創建了一個名為 "hello_world" 在 snake case 風格中,它只是將 hello world 打印到 stdout(終端)。

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 環境(內存)中。但是在這裡,您是在解釋器讀取函數並將其加載到環境中之前調用該函數。

當從另一個函數中調用一個函數時,函數定義可以按任何順序排列,但第一個除外。見下圖。功能 特徵2 稱為 功能 1 什麼時候 特色三 稱為 特徵2 在他們的定義之前。然而 功能 1 先定義,再調用。到……的時候 功能 1 所有被調用的函數定義都已經被解釋並加載到環境中。

從另一個函數調用一個函數從另一個函數調用一個函數

退出狀態和返回值

所有 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

返回一個整數 [N] 獲取值,退出函數,並將返回值提供給調用者(函數)。 在使用 return 語句之前,您應該了解有關如何使用它的一些規則。如前所述,return 接受 0 到 255 之間的整數值。如果未傳遞任何參數(整數值)或值大於 255,則 return 語句使用最後執行的命令的退出狀態。

請讓我通過退貨來解決 "cleanup" 功能行為。這裡我們使用帶有返回命令的條件語句。

#!/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 的特性極大地提高了模塊化和可重用性。

讓我們看一個例子。 我創建了 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 變量之間的差異
  • Bash Echo 命令用 Linux 示例說明
  • Bash Heredoc 初學者教程
  • Bash 重定向示例解釋

BASHBash 函數Bash 腳本Bash PromptCLICommandlineLinuxScriptingShell 腳本