函式
部分內容由 LLM 生成,尚未經過人工驗證。
Shell 函式定義、呼叫、參數傳遞與返回值。
函式定義
Shell 提供兩種函式定義語法:
# 語法 1(推薦)
function_name() {
# 函式內容
}
# 語法 2
function function_name {
# 函式內容
}簡單範例
#!/bin/bash
# 定義函式
greet() {
echo "Hello, World!"
}
# 呼叫函式
greet參數傳遞
函式使用位置參數 $1, $2, $3 等接收參數:
greet() {
local name=$1
local age=$2
echo "Hello, $name! You are $age years old."
}
# 呼叫函式
greet "Alice" 30
# 輸出: Hello, Alice! You are 30 years old.參數相關變數
print_args() {
echo "Function name: $0"
echo "First arg: $1"
echo "Second arg: $2"
echo "All args: $@"
echo "All args (quoted): $*"
echo "Arg count: $#"
}
print_args apple banana cherry$@ vs $*
demo() {
# $@ - 每個參數作為獨立字串
for arg in "$@"; do
echo "[$arg]"
done
echo "---"
# $* - 所有參數作為單一字串
for arg in "$*"; do
echo "[$arg]"
done
}
demo "hello world" "foo" "bar"
# $@ 輸出:
# [hello world]
# [foo]
# [bar]
# $* 輸出:
# [hello world foo bar]返回值
Shell 函式有兩種返回值方式:
return - 返回退出碼
is_even() {
local num=$1
if [ $((num % 2)) -eq 0 ]; then
return 0 # 成功(真)
else
return 1 # 失敗(假)
fi
}
# 使用
if is_even 4; then
echo "Even"
else
echo "Odd"
fi
# 或檢查 $?
is_even 5
if [ $? -eq 0 ]; then
echo "Even"
else
echo "Odd"
fi注意: return 只能返回 0-255 的整數退出碼。
echo - 返回字串
get_full_name() {
local first=$1
local last=$2
echo "${first} ${last}"
}
# 使用命令替換接收輸出
full_name=$(get_full_name "Alice" "Smith")
echo "Full name: $full_name"組合使用
divide() {
local a=$1
local b=$2
if [ $b -eq 0 ]; then
echo "Error: Division by zero" >&2
return 1
fi
echo $((a / b))
return 0
}
# 使用
result=$(divide 10 2)
if [ $? -eq 0 ]; then
echo "Result: $result"
else
echo "Operation failed"
fi局部變數 (local)
使用 local 宣告函式內的局部變數,避免污染全域命名空間:
global_var="I'm global"
test_scope() {
local local_var="I'm local"
global_var="Modified in function"
echo "Inside function:"
echo " local_var: $local_var"
echo " global_var: $global_var"
}
echo "Before function:"
echo " global_var: $global_var"
echo " local_var: $local_var" # 空值
test_scope
echo "After function:"
echo " global_var: $global_var" # 已被修改
echo " local_var: $local_var" # 仍為空函式庫管理 (source)
將常用函式放入獨立檔案,使用 source 或 . 載入:
# lib.sh
greet() {
echo "Hello, $1!"
}
calculate_sum() {
local sum=0
for num in "$@"; do
((sum += num))
done
echo $sum
}# main.sh
#!/bin/bash
# 載入函式庫
source ./lib.sh
# 或
# . ./lib.sh
# 使用載入的函式
greet "Alice"
result=$(calculate_sum 1 2 3 4 5)
echo "Sum: $result"檢查函式是否已定義
if declare -f function_name > /dev/null; then
echo "Function exists"
else
echo "Function not found"
fi遞迴函式
# 階乘
factorial() {
local n=$1
if [ $n -le 1 ]; then
echo 1
else
local prev=$(factorial $((n - 1)))
echo $((n * prev))
fi
}
result=$(factorial 5)
echo "5! = $result" # 120費氏數列
fibonacci() {
local n=$1
if [ $n -le 1 ]; then
echo $n
else
local a=$(fibonacci $((n - 1)))
local b=$(fibonacci $((n - 2)))
echo $((a + b))
fi
}
# 輸出前 10 個費氏數
for i in {0..9}; do
echo "F($i) = $(fibonacci $i)"
done函式作為參數
# 高階函式:接受函式名稱作為參數
apply() {
local func_name=$1
shift # 移除第一個參數
$func_name "$@" # 呼叫傳入的函式
}
double() {
echo $(($ 1 * 2))
}
square() {
echo $(($1 * $1))
}
# 使用
apply double 5 # 10
apply square 5 # 25陣列與函式
# 傳遞陣列到函式
process_array() {
local arr=("$@") # 接收陣列
for item in "${arr[@]}"; do
echo "Processing: $item"
done
}
fruits=("apple" "banana" "cherry")
process_array "${fruits[@]}"函式返回陣列
# 使用全域變數返回陣列
get_even_numbers() {
result=() # 全域陣列
for num in "$@"; do
if [ $((num % 2)) -eq 0 ]; then
result+=("$num")
fi
done
}
get_even_numbers 1 2 3 4 5 6 7 8
echo "Even numbers: ${result[@]}"