在 Shell 脚本中,函数(Function)是用于封装重复逻辑、提高代码复用性的核心工具。以下是 Shell 函数的完整语法和典型用法:
一、函数定义
1. 基础定义方式
# 方式1:使用 function 关键字
function 函数名 {
命令序列
}
# 方式2:省略 function 关键字
函数名() {
命令序列
}
2. 示例:简单函数
# 定义打印欢迎信息的函数
welcome() {
echo "欢迎使用本脚本!当前用户:$(whoami)"
}
# 调用函数
welcome
二、函数参数
1. 传递参数
# 定义加法函数
add() {
sum=$(( $1 + $2 )) # $1 是第一个参数,$2 是第二个参数
echo "结果: $sum"
}
# 调用并传参
add 3 5 # 输出:结果: 8
2. 特殊参数变量
变量 | 含义 |
---|
$# | 参数个数 |
$@ | 所有参数(数组形式) |
$* | 所有参数(字符串形式) |
show_args() {
echo "参数个数: $#"
echo "所有参数: $@"
}
show_args "A" "B" "C" # 输出:参数个数: 3 所有参数: A B C
三、返回值
1. 返回状态码(0-255)
check_file() {
if [ -f "$1" ]; then
return 0 # 文件存在,返回成功
else
return 1 # 文件不存在,返回失败
fi
}
check_file "/etc/passwd"
if [ $? -eq 0 ]; then
echo "文件存在"
fi
2. 返回数据(通过标准输出)
get_size() {
echo $(du -sh "$1" | awk '{print $1}')
}
size=$(get_size "/var/log")
echo "日志目录大小: $size"
四、变量作用域
1. 默认全局变量
global_var="初始值"
modify_var() {
global_var="修改后的值"
}
modify_var
echo "$global_var" # 输出:修改后的值
2. 局部变量(local 关键字)
test_scope() {
local local_var="局部变量"
global_var="全局变量"
}
test_scope
echo "$global_var" # 输出:全局变量
echo "$local_var" # 输出空值(无法访问)
五、高级用法
1. 递归函数
factorial() {
if [ $1 -eq 1 ]; then
echo 1
else
local prev=$(factorial $(( $1 - 1 )))
echo $(( $1 * prev ))
fi
}
echo "5的阶乘: $(factorial 5)" # 输出:120
2. 函数库(复用函数)
# 保存到 lib.sh
print_header() {
echo "===== $1 ====="
date
}
# 主脚本中引用
source lib.sh
print_header "系统信息"
3. 匿名函数(Bash 4.3+)
# 使用子Shell封装临时逻辑
(
tmp_var="临时值"
echo "内部输出: $tmp_var"
) # 退出子Shell后,tmp_var 被销毁
六、错误处理
1. 严格模式(set -e)
# 函数内任何命令失败则终止执行
strict_func() {
set -e
rm non_existent_file # 此命令失败会导致函数退出
echo "不会执行此行"
}
2. 错误捕获(trap)
handle_error() {
echo "错误发生在行号 $1"
exit 1
}
trap 'handle_error $LINENO' ERR
error_func() {
ls /nonexistent_dir # 触发错误
}
七、实际应用示例
1. 文件备份函数
backup_file() {
local src="$1"
local dest="${src}.bak-$(date +%Y%m%d)"
if cp "$src" "$dest"; then
echo "备份成功: $dest"
return 0
else
echo "备份失败!"
return 1
fi
}
backup_file "/etc/nginx/nginx.conf"
2. 服务状态检查
check_service() {
systemctl is-active "$1" >/dev/null 2>&1
return $?
}
if check_service "nginx"; then
echo "Nginx 正在运行"
else
echo "Nginx 未运行"
fi
八、注意事项
1、命名冲突
避免函数名与内置命令或别名重复
2、性能优化
频繁调用的函数应减少外部命令调用
3、代码可读性
复杂函数添加注释说明功能
通过合理使用函数,可以将脚本逻辑模块化,提升代码的可维护性和复用性。建议将常用功能封装成函数库(如 utils.sh),通过 source 命令引入到主脚本中。