一、函数定义与基础用法
1. 定义方式
# 方式1:标准语法(兼容性强)myfunc() {echo "Hello, $1!"}# 方式2:使用 `function` 关键字(可读性高)function myfunc2 {echo "Hello, $1!"}
2. 调用函数
myfunc "World" # 输出: Hello, World!myfunc2 "Shell" # 输出: Hello, Shell!
二、参数与返回值
1. 参数传递
位置参数:$1, $2, ..., ${10}(第10个及以上参数需加大括号)
参数列表:$@(所有参数,保留空格分隔),$*(合并为单个字符串)
参数总数:$#
示例:统计参数并遍历
sum_args() {local total=0for arg in "$@"; dototal=$((total + arg))doneecho "总和: $total"}sum_args 10 20 30 # 输出: 总和: 60
2. 返回值处理
返回状态码:return 0(成功)或 1-255(错误码)
返回数据:通过 echo 捕获输出
get_user() {local uid=$1grep "^$uid:" /etc/passwd | cut -d: -f1return $? # 返回grep命令的退出状态}username=$(get_user 1000)if [[ $? -eq 0 ]]; thenecho "用户存在: $username"fi
三、变量作用域与局部化
1. 避免全局污染
func() {local var="局部变量" # 仅在函数内有效global_var="全局变量" # 外部可访问}funcecho "$var" # 无输出(局部变量已销毁)echo "$global_var" # 输出: 全局变量
2. 动态修改变量(引用传递)
modify_var() {local -n ref=$1 # 通过引用传递变量名ref="新值"}value="旧值"modify_var valueecho "$value" # 输出: 新值
四、高级技巧与调试
1. 函数嵌套与递归
# 递归计算阶乘factorial() {local n=$1if ((n <= 1)); thenecho 1elseecho $((n * $(factorial $((n-1)))))fi}echo "5! = $(factorial 5)" # 输出: 5! = 120
2. 错误处理与调试
严格模式:在脚本开头添加 set -euo pipefail(遇错退出、未定义变量报错、管道失败检测)
调试输出:
debug_func() {set -x # 开启调试local cmd=$1$cmdset +x # 关闭调试}debug_func "ls -l"
五、实战场景示例
1. 批量重命名文件
batch_rename() {local ext=$1local prefix=$2local i=1for file in *."$ext"; domv "$file" "${prefix}_${i}.${ext}"((i++))done}batch_rename "jpg" "photo" # 重命名所有.jpg文件为photo_1.jpg, photo_2.jpg...
2. 系统监控报警
check_disk() {local threshold=$1local usage=$(df -h / | awk 'NR==2 {print $5}' | tr -d '%')if ((usage >= threshold)); thenecho "警告: 磁盘使用率超过 ${threshold}% (当前: ${usage}%)" >&2return 1fireturn 0}check_disk 90 || send_alert_email # 触发邮件报警
3. 自动化备份
backup_dir() {local src=$1local dest="/backup/$(basename $src)_$(date +%Y%m%d).tar.gz"tar -czf "$dest" "$src" && echo "备份成功: $dest"}backup_dir "/var/www" # 生成/backup/www_20231001.tar.gz
六、性能优化建议
减少子进程调用:避免在循环中频繁调用外部命令(如 awk、sed),改用内置字符串操作。
预加载函数:将常用函数定义在单独文件中,通过 source utils.sh 导入。
避免递归过深:Bash 默认栈深度有限(可通过 ulimit -s 调整),复杂计算建议改用循环。
七、常见问题解决
| 问题 | 解决方案 |
|---|---|
func "$arg" | |
echo输出结果,通过 $(func)捕获 | |
declare -n或全局变量(谨慎使用) | |
$?被覆盖 | output=$(func); ret=$? |
掌握函数技巧,编写高效、易维护的 Bash 脚本,轻松应对自动化运维、数据处理等场景
文章转载自老柴杂货铺,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。




