通过ssh在远程机器上按索引访问数组元素

huangapple go评论70阅读模式
英文:

Accessing array elements by index on a remote machine via ssh

问题

在一个远程机器上,我需要同时获取两个数组的值。也就是说,第一个和第二个数组的第1个元素,然后是第1和第2个数组的第2个元素,以此类推。

在编写脚本时,我遇到了一个问题,当我使用变量指定数组索引时,只显示数组的第一个元素,没有其他结果。我尝试过使用转义和这样写 [$i],但没有结果。我做错了什么?正确的方法是如何访问数组元素的索引?

我想要获取的结果如下:

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

请注意,这是您提供的代码示例的翻译部分。

英文:

On a remote machine, I need to get the values ​​of 2 arrays at the same time. That is, 1 element of 1 and 2 arrays, then 2 element of 1 and 2 arrays, and so on.

When writing a script, I ran into a problem that when I specify the array index using a variable, only the first element of the array is displayed and that's it. I tried escaping and writing like this [$i] but no result. What am I doing wrong? And what is the right way to access array elements by index?

What i want to get:

array1=(&quot;1&quot; &quot;2&quot;)
array2=(&quot;a&quot; &quot;b&quot;)

ssh $user_srv@$ip_srv -p $port_srv &#39;bash -s&#39; &lt;&lt; EOF
for i in &quot;${!array1[@]}&quot;
do
    echo &#39;${array1[$i]}&#39;
    echo &#39;${array2[$i]}&#39;
done
EOF

Result:

1
a
2
b

答案1

得分: 7

定义要运行的代码为一个本地函数;然后使用declare -f来序列化该函数,使用declare -p来序列化它使用的数据,以便将它们传输到远程服务器。

array1=("1" "2")
array2=("a" "b")

rmt_func() {
  for i in "${!array1[@]}"; do
    echo "${array1[$i]}"
    echo "${array2[$i]}"
  done
}

ssh "$user_srv@$ip_srv" -p "$port_srv" 'bash -s' <<EOF
  $(declare -p array1 array2)
  $(declare -f rmt_func)
  rmt_func
EOF
英文:

Define the code you want to run as a local function; then use declare -f to serialize that function, and declare -p to serialize the data it uses, to pass them over the wire.

array1=(&quot;1&quot; &quot;2&quot;)
array2=(&quot;a&quot; &quot;b&quot;)

rmt_func() {
  for i in &quot;${!array1[@]}&quot;; do
    echo &quot;${array1[$i]}&quot;
    echo &quot;${array2[$i]}&quot;
  done
}

ssh &quot;$user_srv@$ip_srv&quot; -p &quot;$port_srv&quot; &#39;bash -s&#39; &lt;&lt;EOF
  $(declare -p array1 array2)
  $(declare -f rmt_func)
  rmt_func
EOF

答案2

得分: 0

这段代码解决了远程机器上不存在数组的问题,它通过在本地机器上循环遍历数组并生成printf命令来发送到远程机器以打印元素:

array1=("1" "2")
array2=("a" "b")

for i in "${!array1[@]}"; do
    printf 'printf "%%s\\\\n" %q\n' "${array1[i]}"
    printf 'printf "%%s\\\\n" %q\n' "${array2[i]}"
done | ssh "$user_srv@$ip_srv" -p "$port_srv" 'bash -s'
  • 使用printf%q格式可以使相应的参数(在本例中是数组元素)以可重用作为shell输入的格式输出。这确保了该代码适用于包含空格或shell元字符的数组元素。
  • echo 不安全,不能用于打印任意字符串值,所以我使用了 printf。请参考接受的、出色的答案 Why is printf better than echo?
英文:

Since the arrays don't exist on the remote machine, this code solves the problem by looping through the arrays on the local machine and generating printf commands to send to the remote machine to print the elements:

array1=(&quot;1&quot; &quot;2&quot;)
array2=(&quot;a&quot; &quot;b&quot;)

for i in &quot;${!array1[@]}&quot;; do
    printf &#39;printf &quot;%%s\\\\n&quot; %q\n&#39; &quot;${array1[i]}&quot;
    printf &#39;printf &quot;%%s\\\\n&quot; %q\n&#39; &quot;${array2[i]}&quot;
done | ssh &quot;$user_srv@$ip_srv&quot; -p &quot;$port_srv&quot; &#39;bash -s&#39;
  • The %q format with printf causes the corresponding argument (in this case an array element) to be output in a format that can be reused as shell input. That ensures that the code works for array elements that contain whitespace or shell metacharacters.
  • echo is not safe for printing arbitrary string values so I used printf instead. See the accepted, and excellent, answer to Why is printf better than echo?.

huangapple
  • 本文由 发表于 2023年6月30日 03:09:06
  • 转载请务必保留本文链接:https://go.coder-hub.com/76583980.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定