Shell脚本变量与函数变量

在 shell 脚本中使用$1, $2 等表示变量,它们不仅可以表示脚本的参数,也可以表示函数的参数。但是,如果一个函数它自己有参变量,同时又需要引用脚本的参变量,那这个函数就无法识别$1是脚本的还是函数的,这会导致矛盾。为了解决函数参数覆盖脚本参数的问题,一个简单安全的方法是提前保存脚本参数,即

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
#!/bin/bash
# 调用前保存脚本参数到全局变量
script_args=("$@")  # 保存所有参数到数组
process_args() {
    # 函数参数
    local func_param="$1"
    # 访问脚本参数
    echo "脚本第一个参数: ${script_args[0]}"
    echo "脚本第二个参数: ${script_args[1]}"
    echo "函数参数: $func_param"
    # 遍历所有脚本参数
    for arg in "${script_args[@]}"; do
        echo "脚本参数: $arg"
    done
}
# 调用函数并传递函数参数
process_args "函数参数值"

此法能确保在函数中正确访问脚本参数,同时保持代码清晰和可维护性。 这里需要注意变量$0和$?不会被函数参数覆盖,这里将各变量列表如下:

变量是否被函数参数覆盖作用域说明
$0否全局始终表示脚本名称
$?否动态更新始终表示上一个命令的退出状态
$1-$9是函数内局部在函数内被函数参数覆盖
$#是函数内局部在函数内表示函数参数个数
$@是函数内局部在函数内表示函数参数列表

所以综合考虑,将$0也在脚本开头保存,以便规范使用。于是前面的脚本可以进一步写为:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
#!/bin/bash
# 调用前保存脚本参数到全局变量
script_args=("$0" "$@")  # 保存所有参数到数组
process_args() {
    # 函数参数
    local func_param="$1"
    # 访问脚本参数
    echo "脚本第一个参数: ${script_args[0]}"
    echo "脚本第二个参数: ${script_args[1]}"
    echo "函数参数: $func_param"
    # 遍历所有脚本参数
    for arg in "${script_args[@]}"; do
        echo "脚本参数: $arg"
    done
}
# 调用函数并传递函数参数
process_args "函数参数值"