SSH远程机器上按索引访问数组元素:变量索引失效问题排查
Bash远程执行时数组遍历的问题解决
问题背景
需要在远程机器上同时遍历两个本地数组,依次取出对应索引的元素,但编写的脚本仅能显示数组第一个元素,转义写法也无效。原代码示例:
array1=("1" "2") array2=("a" "b") ssh $user_srv@$ip_srv -p $port_srv 'bash -s' << EOF for i in "${!array1[@]}" do echo '${array1[$i]}' echo '${array2[$i]}' done EOF
期望输出:
1 a 2 b
错误原因
- 数组未传递到远程环境:本地定义的
array1和array2仅存在于当前本地Shell,远程执行的Bash进程无法直接访问这些变量。 - 单引号阻止变量展开:原脚本中
echo '${array1[$i]}'用单引号包裹,内容会被当作纯字符串输出,不会解析变量和索引。 - 本地提前解析变量:即使去掉单引号,由于未对EOF加引号,本地Shell会先尝试展开
${array1[$i]},但此时本地$i未定义,会变成${array1[]},最终只取到数组第一个元素。
正确解法
方法1:序列化数组后传递到远程
将本地数组序列化为字符串,传递到远程后再还原为数组:
array1=("1" "2") array2=("a" "b") # 序列化数组,元素用换行分隔 serialized_array1=$(printf "%s\n" "${array1[@]}") serialized_array2=$(printf "%s\n" "${array2[@]}") ssh $user_srv@$ip_srv -p $port_srv 'bash -s' << EOF # 在远程环境还原数组 readarray -t array1 <<< "$serialized_array1" readarray -t array2 <<< "$serialized_array2" # 遍历数组索引 for i in "\${!array1[@]}" do echo "\${array1[\$i]}" echo "\${array2[\$i]}" done EOF
方法2:将数组元素作为位置参数传递
把数组长度和所有元素作为参数传递给远程Bash:
array1=("1" "2") array2=("a" "b") # 传递数组长度、array1元素、array2元素 ssh $user_srv@$ip_srv -p $port_srv 'bash -s' "${#array1[@]}" "${array1[@]}" "${array2[@]}" << EOF # 从参数中还原数组 len=\$1 shift array1=("\${@:1:\$len}") array2=("\${@:\$((len+1))}") # 遍历索引 for ((i=0; i<len; i++)) do echo "\${array1[i]}" echo "\${array2[i]}" done EOF
两种方法都能确保数组完整传递到远程环境,远程脚本中的变量需加反斜杠转义,避免本地Shell提前解析。
内容的提问来源于stack exchange,提问作者Lozb1k
相关产品推荐
相关产品推荐

