在 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 "函数参数值"
|