乐闻世界logo
搜索文章和话题

Shell 脚本中如何定义和调用函数?如何传递参数和返回值?

3月6日 21:33

Shell 脚本中函数的定义、调用和参数传递机制如下:

函数定义

基本语法

bash
function_name() { commands } # 或者使用 function 关键字 function function_name { commands }

函数定义示例

bash
# 简单函数 greet() { echo "Hello, World!" } # 带参数的函数 greet_user() { echo "Hello, $1!" } # 带多个参数的函数 add() { local sum=$(($1 + $2)) echo "Sum: $sum" } # 带默认值的函数 backup_file() { local file=${1:-"default.txt"} local backup_dir=${2:-"./backup"} echo "Backing up $file to $backup_dir" }

函数调用

基本调用

bash
# 定义函数 greet() { echo "Hello, World!" } # 调用函数 greet # 输出: Hello, World!

传递参数

bash
# 定义带参数的函数 greet_user() { echo "Hello, $1!" } # 调用并传递参数 greet_user "John" # 输出: Hello, John! # 传递多个参数 add() { echo "$1 + $2 = $(($1 + $2))" } add 5 3 # 输出: 5 + 3 = 8

函数参数

位置参数

bash
show_args() { echo "First argument: $1" echo "Second argument: $2" echo "Third argument: $3" echo "All arguments: $@" echo "Number of arguments: $#" } show_args "apple" "banana" "cherry" # 输出: # First argument: apple # Second argument: banana # Third argument: cherry # All arguments: apple banana cherry # Number of arguments: 3

处理可变参数

bash
# 处理任意数量的参数 sum_all() { local total=0 for num in "$@"; do total=$((total + num)) done echo "Total: $total" } sum_all 1 2 3 4 5 # 输出: Total: 15

局部变量

local 关键字

bash
# 使用 local 声明局部变量 counter=0 increment() { local counter=10 echo "Inside function: $counter" counter=$((counter + 1)) echo "After increment: $counter" } increment echo "Outside function: $counter" # 输出: # Inside function: 10 # After increment: 11 # Outside function: 0

局部变量的重要性

bash
# 不使用 local 会导致全局变量被修改 global_var="original" bad_function() { global_var="modified" } good_function() { local global_var="local only" echo "Local: $global_var" } bad_function echo "After bad_function: $global_var" # 输出: After bad_function: modified good_function echo "After good_function: $global_var" # 输出: After good_function: modified

返回值

使用 return 返回状态码

bash
check_file() { if [ -f "$1" ]; then return 0 # 成功 else return 1 # 失败 fi } check_file "/etc/passwd" if [ $? -eq 0 ]; then echo "File exists" else echo "File does not exist" fi

使用 echo 返回值

bash
# 返回字符串或计算结果 get_username() { echo "John Doe" } username=$(get_username) echo "Username: $username" # 输出: Username: John Doe # 返回计算结果 calculate() { echo $(($1 * $2)) } result=$(calculate 5 4) echo "Result: $result" # 输出: Result: 20

返回数组

bash
get_array() { local arr=("apple" "banana" "cherry") echo "${arr[@]}" } fruits=($(get_array)) for fruit in "${fruits[@]}"; do echo "Fruit: $fruit" done

函数库和导入

创建函数库

bash
# 文件: mylib.sh #!/bin/bash log_info() { echo "[INFO] $(date '+%Y-%m-%d %H:%M:%S') - $1" } log_error() { echo "[ERROR] $(date '+%Y-%m-%d %H:%M:%S') - $1" >&2 } check_command() { if command -v "$1" >/dev/null 2>&1; then return 0 else return 1 fi }

导入函数库

bash
#!/bin/bash # 导入函数库 source ./mylib.sh # 或者 . ./mylib.sh # 使用库中的函数 log_info "Script started" if check_command "git"; then log_info "Git is installed" else log_error "Git is not installed" fi

实际应用示例

bash
#!/bin/bash # 函数 1: 检查文件是否存在 check_file() { local file=$1 if [ -f "$file" ]; then return 0 else return 1 fi } # 函数 2: 创建备份 create_backup() { local source=$1 local backup_dir=${2:-"./backup"} if ! check_file "$source"; then echo "Error: File $source does not exist" return 1 fi mkdir -p "$backup_dir" local timestamp=$(date +%Y%m%d_%H%M%S) local backup_file="$backup_dir/$(basename $source).$timestamp" cp "$source" "$backup_file" echo "Backup created: $backup_file" return 0 } # 函数 3: 批量处理文件 process_files() { local pattern=$1 local count=0 for file in $pattern; do if [ -f "$file" ]; then echo "Processing: $file" create_backup "$file" count=$((count + 1)) fi done echo "Processed $count files" return 0 } # 函数 4: 显示使用帮助 show_help() { echo "Usage: $0 [options]" echo "Options:" echo " -f <file> Backup single file" echo " -p <pattern> Backup files matching pattern" echo " -h Show this help" } # 主程序 main() { case $1 in -f) if [ -n "$2" ]; then create_backup "$2" else echo "Error: No file specified" show_help fi ;; -p) if [ -n "$2" ]; then process_files "$2" else echo "Error: No pattern specified" show_help fi ;; -h) show_help ;; *) echo "Error: Invalid option" show_help ;; esac } # 执行主程序 main "$@"

函数最佳实践

  1. 使用 local 声明局部变量: 避免污染全局命名空间
  2. 函数名使用小写: 遵循 Shell 命名约定
  3. 添加注释: 说明函数用途和参数
  4. 检查参数: 验证输入参数的有效性
  5. 返回适当的退出码: 0 表示成功,非 0 表示失败
  6. 使用函数库: 将常用函数组织到单独的文件中
  7. 避免副作用: 函数应该专注于单一职责
标签:Shell