如何在Bash脚本中通过循环利用位置参数定义变量?
Bash批量定义对应位置参数的变量(解决赋值为字符串而非实际值的问题)
问题原因
你遇到的问题是直接用declare赋值时,未对位置参数的变量引用做扩展,导致变量存储的是$3这类字符串,而非位置参数的实际内容。比如declare mid_2=\$$pos会把字符串"$3"赋值给mid_2,而不是$3对应的实际参数值。
解决方案
下面提供两种可靠的实现方式,按需选择:
方法1:使用eval(兼容所有Bash版本)
eval会先解析字符串中的变量引用,再执行赋值操作,能正确将位置参数的实际值赋给目标变量:
#!/bin/bash # 按mid_1=$1、freq_1=$2、mid_2=$3、freq_2=$4的规则批量赋值 count=1 pos=1 while [ $pos -le $# ]; do # 给mid_$count赋值为第pos个位置参数 eval "mid_$count=\$$pos" pos=$((pos + 1)) # 给freq_$count赋值为第pos个位置参数 eval "freq_$count=\$$pos" pos=$((pos + 1)) count=$((count + 1)) done
方法2:使用declare -n(Bash 4.3+,更安全)
declare -n是Bash的名字引用特性,能直接关联目标变量,避免eval的潜在安全风险:
#!/bin/bash count=1 pos=1 while [ $pos -le $# ]; do # 建立mid_$count的名字引用 declare -n current_mid="mid_$count" # 间接引用第pos个位置参数的值,赋值给mid_$count current_mid=${!pos} pos=$((pos + 1)) declare -n current_freq="freq_$count" current_freq=${!pos} pos=$((pos + 1)) count=$((count + 1)) done
正确输出变量值
要输出批量定义的变量值,需要使用间接引用或名字引用,不能直接输出变量名字符串:
搭配方法1的输出方式(间接引用)
# 循环输出所有mid和freq变量的值 for ((i=1; i<count; i++)); do # ${!varname} 是间接引用语法,获取varname对应的变量值 echo "mid_$i = ${!mid_$i}" echo "freq_$i = ${!freq_$i}" done
搭配方法2的输出方式(名字引用)
for ((i=1; i<count; i++)); do declare -n current_mid="mid_$i" declare -n current_freq="freq_$i" echo "mid_$i = $current_mid" echo "freq_$i = $current_freq" done
测试示例
执行脚本时传入参数:
./script.sh 100 50 200 60
输出结果:
mid_1 = 100 freq_1 = 50 mid_2 = 200 freq_2 = 60
内容的提问来源于stack exchange,提问作者Liu Yu
相关产品推荐
相关产品推荐

