You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

BASH SSH脚本中如何将远程循环数组索引传递给全局函数使用

问题根因
  • 你写在SSH双引号内的变量默认会被本地Bash在执行SSH命令前提前展开,不会传到远程再解析。你代码里的${usr1[$j]}中的$j是本地变量,SSH执行前本地没有给j赋值,默认取值为空,所以永远取到的是${usr1[0]}即user1。
  • 你定义的tusr是本地函数,写在命令替换$(tusr usr1 "\$j")里的逻辑也是在本地执行的,同样因为本地j为空,永远返回user1。
  • 你之前尝试转义$j时出现语法报错,是因为转义后的\$j在本地展开时会变成字符串$j,本地数组需要数字作为索引,把字符串$j当索引就会触发 operand expected 错误。
  • 额外补充:你的本地数组usr1和函数tusr都不会被自动传到远程主机,就算你成功把$j传到了远程,远程也找不到对应的数组和函数,依然无法正常执行。
修复方案

最简单稳定的实现方式是先把本地的数组、函数定义序列化后传到远程,再在远程执行遍历逻辑,修改后可运行的代码如下:

usr1=("user1" "user2")

# 如果要保留自定义函数,可以保留,后续导出到远程即可
function tusr {
     declare -n tmpp="$1";
     echo "${tmpp[$j]}"
 }

 function testchk {
 echo "Logging in as $myuser to $1"
 # 导出本地数组和函数的定义
 local arr_def="$(declare -p usr1)"
 local func_def="$(declare -f tusr)"
 # 远程先恢复数组、函数定义,再执行遍历逻辑,所有远程要用到的变量全部加转义
 ssh -tq $myuser@$1.bar.com "
 $arr_def
 $func_def
 for j in \${!usr1[@]}; do
         echo \$j
         echo \${usr1[\$j]}
         echo \"Checking \$(tusr usr1 \$j):\"
 done
 "
 }

 srv="foo"
 testchk "$srv"

如果不需要保留tusr函数,可以直接在远程用数组取值,简化代码:

usr1=("user1" "user2")

function testchk {
 echo "Logging in as $myuser to $1"
 local arr_def="$(declare -p usr1)"
 ssh -tq $myuser@$1.bar.com "
 $arr_def
 for j in \${!usr1[@]}; do
         echo \$j
         echo \${usr1[\$j]}
         echo \"Checking \${usr1[\$j]}:\"
 done
 "
 }

 srv="foo"
 testchk "$srv"

两种方案的执行结果都和你预期的输出一致。

内容的提问来源于stack exchange,提问作者qwedcxzas

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.27 14:54:03