Linux

Bash 程式設計教學與範例:function 自訂函數

介紹如何在 bash shell 指令稿中自行定義與使用函數(function)。

定義函數

在 bash shell 指令稿中可以像一般程式語言一樣自己定義函數,以下是一個簡單的範例:

# 定義函數
function hello () {
  echo "Hello, world."
}

定義好函數之後,就可以像普通的指令一樣呼叫使用:

# 呼叫函數
hello
Hello, world.

上面那種定義函數的寫法是最完整的版本,我們也可以將 function 這個關鍵字省略:

# 定義函數(簡略寫法)
hello2 () {
  echo "Hello, World."
}

或是將後方的一對小括號省略:

# 定義函數(簡略寫法)
function hello3 {
  echo "Hello, World."
}

不管用哪一種寫法,對於程式來說效果都一樣,差異只在於程式碼是否清晰好讀。

傳入參數

呼叫 bash 函數的時候,也可以透過參數將資料傳遞至函數之中,函數的參數不需要事先定義,只要直接在函數之中以 $1$2$3 … 等特殊變數取得傳入的參數即可,$1 代表第一個傳入的參數,$1 則代表第二個傳入的參數,以此類推:

# 在函數中取得傳入參數
function greeting () {
  echo "Hello, $1."
}

# 呼叫函數並傳入參數
greeting "Joe"
Hello, Joe.

bash 函數可以動態接受任意數量的參數,傳入參數的數量可以從 $# 這個特殊變數取得,而所有的參數則可統一從 $*$@ 兩個特殊變數中取得:

# 可接受任意數量參數的函數
function greeting2 () {
  # 取得參數數量
  echo "數量:$#"

  # 逐一處理每一個參數 
  for name in $*
  do
    echo "Hello, $name."
  done
}

# 傳入任意數量參數
greeting2 "Joe" "Mary" "Adora"
數量:3
Hello, Joe.
Hello, Mary.
Hello, Adora.

$*$@ 的差別在於放在雙引號之中的時候,"$*" 會轉換為 "$1 $2 $3 ...",而 "$@" 會轉換為 "$1" "$2" "$3" ...,除此之外兩者沒有其他的差異。

函數傳回值

bash 的函數無法像普通的程式語言一樣可以傳回任意的值,當 bash 函數執行結束之後,只會傳回一個整數的傳回值,代表執行成功與否,0 代表成功,而 1255 則代表各種錯誤。

若要指定函數的傳回數值,可以使用 return,然後搭配 $? 來取得函數的傳回值,而通常我們在取得函數的傳回值之後,會接著判斷函數是否有執行成功。

function myfunc () {
  # 函數傳回值
  return 35
}

# 呼叫函數
myfunc

# 取得傳回值
val=$?

# 根據傳回值判斷成功與否
if [ ! $val -eq 0 ]; then
  echo "執行失敗,錯誤代碼:$val"
fi
執行失敗,錯誤代碼:35

全域變數傳遞資料

如果需要從函數中傳回整數以外的資料,最簡單的辦法就是透過全域變數傳遞:

function myfunc () {
  # 將結果儲存至全域變數中
  result="my result"
}

# 呼叫函數
myfunc

# 透過全域變數取得執行結果
echo $result
my result

透過標準輸出傳遞資料

除了使用全域變數傳回資料之外,也可以運用標準輸出來傳遞,這種作法比較複雜一些,但是可以避免使用全域變數:

function myfunc () {
  # 將結果輸出至標準輸出
  echo "my result"
}

# 呼叫函數,並從標準輸出取得傳回的資料
result=$(myfunc)

# 輸出結果
echo $result
my result

變數範圍

bash 函數內部所定義的變數預設都是全域變數,如果需要定義一個只有在函數內部使用的區域變數,可以使用 local 關鍵字:

# 全域變數
var1='A'
var2='B'

function myfunc () {
  # 定義區域變數
  local var1='C'

  # 改變全域變數
  var2='D'

  echo "函數內部:   var1=$var1, var2=$var2"
}

echo "函數執行前: var1=$var1, var2=$var2"

# 執行函數
myfunc

echo "函數執行後: var1=$var1, var2=$var2"
函數執行前: var1=A, var2=B
函數內部:   var1=C, var2=D
函數執行後: var1=A, var2=D

凡是以 local 所定義的區域變數都只會存在於函數之中,不會影響到函數以外的全域變數。

參考資料:鳥哥的 Linux 私房菜GNULinuxize

Share
Published by
Office Guide
Tags: Bash

Recent Posts

Python 使用 PyAutoGUI 自動操作滑鼠與鍵盤

本篇介紹如何在 Python ...

1 年 ago

Ubuntu Linux 以 WireGuard 架設 VPN 伺服器教學與範例

本篇介紹如何在 Ubuntu ...

1 年 ago

Linux 網路設定 ip 指令用法教學與範例

本篇介紹如何在 Linux 系...

1 年 ago

Linux 以 Cryptsetup、LUKS 加密 USB 隨身碟教學與範例

介紹如何在 Linux 系統中...

1 年 ago