开发工具

Shell 函数

13 篇文章69 次收藏
上一节:Shell until 语句下一节:Shell 数组

在 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 命令引入到主脚本中。


上一节:Shell until 语句下一节:Shell 数组