Appearance
函数参数
位置参数
基本用法
bash
#!/bin/bash
# 定义函数
greet() {
echo "Hello, $1!"
echo "你的年龄是: $2"
}
# 调用函数
greet "张三" 25访问所有参数
bash
#!/bin/bash
# 定义函数
print_all_args() {
echo "所有参数: $@"
echo "参数个数: $#"
}
# 调用函数
print_all_args "apple" "banana" "orange"遍历参数
bash
#!/bin/bash
# 定义函数
print_args() {
echo "参数个数: $#"
for arg in "$@"; do
echo "参数: $arg"
done
}
# 调用函数
print_args "a" "b" "c" "d"特殊参数
$@ 和 $*
bash
#!/bin/bash
# 定义函数
test_special_params() {
echo "使用 \$@:"
for arg in "$@"; do
echo " $arg"
done
echo "使用 \$*:"
for arg in "$*"; do
echo " $arg"
done
}
# 调用函数
test_special_params "a b" "c d"$#
bash
#!/bin/bash
# 定义函数
count_args() {
echo "参数个数: $#"
}
# 调用函数
count_args "a" "b" "c"
count_args$0
bash
#!/bin/bash
# 定义函数
show_script_name() {
echo "脚本名称: $0"
}
# 调用函数
show_script_name默认参数
设置默认值
bash
#!/bin/bash
# 定义带默认参数的函数
greet() {
local name=${1:-"World"}
echo "Hello, $name!"
}
# 调用函数
greet "张三"
greet多个默认参数
bash
#!/bin/bash
# 定义带多个默认参数的函数
create_file() {
local filename=${1:-"default.txt"}
local content=${2:-"默认内容"}
echo "$content" > "$filename"
echo "文件创建成功: $filename"
}
# 调用函数
create_file "test.txt" "测试内容"
create_file参数验证
检查参数数量
bash
#!/bin/bash
# 定义带参数验证的函数
add() {
if [ $# -ne 2 ]; then
echo "错误: 需要 2 个参数"
return 1
fi
echo $(($1 + $2))
}
# 调用函数
result=$(add 10 20)
echo "10 + 20 = $result"
result=$(add 10)
echo "10 = $result"检查参数类型
bash
#!/bin/bash
# 定义带参数类型检查的函数
is_number() {
local num="$1"
[[ "$num" =~ ^-?[0-9]+$ ]]
}
# 定义函数
multiply() {
if ! is_number "$1" || ! is_number "$2"; then
echo "错误: 参数必须是数字"
return 1
fi
echo $(($1 * $2))
}
# 调用函数
result=$(multiply 10 20)
echo "10 * 20 = $result"
result=$(multiply "a" "b")
echo "a * b = $result"检查参数是否为空
bash
#!/bin/bash
# 定义带空值检查的函数
print_upper() {
if [ -z "$1" ]; then
echo "错误: 参数不能为空"
return 1
fi
echo "$1" | tr '[:lower:]' '[:upper:]'
}
# 调用函数
result=$(print_upper "hello")
echo "hello -> $result"
result=$(print_upper "")
echo " -> $result"命名参数
使用关联数组
bash
#!/bin/bash
# 定义使用命名参数的函数
create_user() {
local -A params
params["name"]="$1"
params["age"]="$2"
params["city"]="$3"
echo "姓名: ${params["name"]}"
echo "年龄: ${params["age"]}"
echo "城市: ${params["city"]}"
}
# 调用函数
create_user "张三" 25 "北京"解析命名参数
bash
#!/bin/bash
# 定义解析命名参数的函数
parse_args() {
while [ $# -gt 0 ]; do
case "$1" in
--name=*)
name="${1#*=}"
;;
--age=*)
age="${1#*=}"
;;
--city=*)
city="${1#*=}"
;;
*)
echo "未知参数: $1"
return 1
;;
esac
shift
done
echo "姓名: $name"
echo "年龄: $age"
echo "城市: $city"
}
# 调用函数
parse_args --name="张三" --age=25 --city="北京"可变参数
处理可变数量的参数
bash
#!/bin/bash
# 定义处理可变参数的函数
sum() {
local total=0
for num in "$@"; do
total=$((total + num))
done
echo $total
}
# 调用函数
result=$(sum 1 2 3 4 5)
echo "1 + 2 + 3 + 4 + 5 = $result"
result=$(sum 10 20 30)
echo "10 + 20 + 30 = $result"混合固定参数和可变参数
bash
#!/bin/bash
# 定义混合参数的函数
concat() {
local separator="$1"
shift
local result=""
for item in "$@"; do
if [ -z "$result" ]; then
result="$item"
else
result="$result$separator$item"
fi
done
echo "$result"
}
# 调用函数
result=$(concat "-" "a" "b" "c" "d")
echo "结果: $result"参数数组
传递数组
bash
#!/bin/bash
# 定义接收数组的函数
process_array() {
local arr=("$@")
echo "数组长度: ${#arr[@]}"
for item in "${arr[@]}"; do
echo " $item"
done
}
# 调用函数
my_array=("apple" "banana" "orange")
process_array "${my_array[@]}"返回数组
bash
#!/bin/bash
# 定义返回数组的函数
get_fruits() {
local fruits=("apple" "banana" "orange")
echo "${fruits[@]}"
}
# 调用函数
fruits=($(get_fruits))
echo "水果列表:"
for fruit in "${fruits[@]}"; do
echo " $fruit"
done实用示例
示例1:文件操作函数
bash
#!/bin/bash
# 创建文件
create_file() {
local filename="$1"
local content="$2"
if [ -z "$filename" ]; then
echo "错误: 文件名不能为空"
return 1
fi
echo "${content:-默认内容}" > "$filename"
echo "文件创建成功: $filename"
}
# 删除文件
delete_file() {
local filename="$1"
if [ -z "$filename" ]; then
echo "错误: 文件名不能为空"
return 1
fi
if [ ! -f "$filename" ]; then
echo "错误: 文件不存在: $filename"
return 1
fi
rm "$filename"
echo "文件删除成功: $filename"
}
# 使用函数
create_file "test.txt" "测试内容"
delete_file "test.txt"示例2:字符串处理函数
bash
#!/bin/bash
# 字符串拼接
concat() {
local separator="$1"
shift
local result=""
for item in "$@"; do
if [ -z "$result" ]; then
result="$item"
else
result="$result$separator$item"
fi
done
echo "$result"
}
# 字符串查找
find_string() {
local string="$1"
local substring="$2"
if [[ "$string" == *"$substring"* ]]; then
return 0
else
return 1
fi
}
# 使用函数
result=$(concat "-" "a" "b" "c")
echo "拼接结果: $result"
if find_string "hello world" "world"; then
echo "找到子串"
else
echo "未找到子串"
fi示例3:数学运算函数
bash
#!/bin/bash
# 加法
add() {
echo $(($1 + $2))
}
# 减法
subtract() {
echo $(($1 - $2))
}
# 乘法
multiply() {
echo $(($1 * $2))
}
# 除法
divide() {
if [ $2 -eq 0 ]; then
echo "错误: 除数不能为 0"
return 1
fi
echo $(($1 / $2))
}
# 使用函数
result=$(add 10 20)
echo "10 + 20 = $result"
result=$(subtract 20 10)
echo "20 - 10 = $result"
result=$(multiply 10 20)
echo "10 * 20 = $result"
result=$(divide 20 10)
echo "20 / 10 = $result"示例4:日志函数
bash
#!/bin/bash
# 日志函数
log() {
local level="$1"
shift
local message="$@"
local timestamp=$(date '+%Y-%m-%d %H:%M:%S')
echo "[$timestamp] [$level] $message"
}
# 信息日志
info() {
log "INFO" "$@"
}
# 警告日志
warn() {
log "WARN" "$@"
}
# 错误日志
error() {
log "ERROR" "$@"
}
# 使用函数
info "程序启动"
warn "配置文件不存在"
error "连接失败"最佳实践
1. 验证参数
bash
# 好的做法
func() {
if [ $# -lt 1 ]; then
echo "错误: 缺少参数"
return 1
fi
echo "$1"
}
# 不好的做法
func() {
echo "$1"
}2. 使用默认值
bash
# 好的做法
func() {
local param=${1:-"默认值"}
echo "$param"
}
# 不好的做法
func() {
local param="$1"
if [ -z "$param" ]; then
param="默认值"
fi
echo "$param"
}3. 使用引号
bash
# 好的做法
func() {
for arg in "$@"; do
echo "$arg"
done
}
# 不好的做法
func() {
for arg in $@; do
echo $arg
done
}总结
函数参数的关键点:
- 位置参数:
$1,$2,$3, ... - 特殊参数:
$@,$*,$#,$0 - 默认参数:
${param:-"默认值"} - 参数验证:检查数量、类型、是否为空
- 命名参数:使用关联数组或解析参数
- 可变参数:处理可变数量的参数
- 参数数组:传递和返回数组
下一节我们将学习函数作用域的使用。