如何并行运行多个 ssh 命令并将输出存储到变量中

如何并行运行多个 ssh 命令并将输出存储到变量中

我尝试编写一个 shell 脚本,通过 登录多个主机ssh,执行一些命令,并打印执行摘要。到目前为止,我已经编写了一个可以在顺序的方式。但是很慢,我想以并行的方式重写它。我知道我可以用来&并行运行多个 ssh 命令,并使用“命令替换”将subshell输出存储到变量中。但我无法正确地将它们组合起来。

到目前为止,我已经输出了这些代码。但它仍然按顺序运行。

#!/bin/bash

hosts=( 'host-1' 'host-2' 'host-3' )

cmd='sleep $[ (( $RANDOM % 20 ) + 1) /10 ]s && echo hello world'
i=0
for host in ${hosts[@]}; do
    var1=$(ssh $host $cmd &)
    echo "i = $i"
    outputs[i]="$var1"
    ((i++))
done

echo 'wait'
wait

echo ${outputs[@]}

答案1

我认为您不能在后台有效地使用变量分配(无论是否使用命令替换),因为后台作业在子 shell 中运行。例如

foo=x
foo=$(echo y) &
echo "$foo"

将打印x第二个分配仅适用于子 shell。

另一方面,在命令替换内部后台运行也不会执行您想要的操作,shell 无论如何都会等待命令,并且您会按顺序执行任务:

sleepecho() { sleep "$1"; echo "$2"; }
foo=$( sleepecho 5 abc & )      # returns after five seconds
echo "$foo"                     # prints 'abc'

您可以做的是将命令的输出存储在临时文件中。这将使背景工作,并且如果输出很长也可能更好。

dir=$(mktemp -d)
for h in "${hosts[@]}" ; do
    ssh "$h" "$cmd" > "$dir/$h" & 
done
wait
do something with "$dir/"*

尽管有许多现成的解决方案可以通过ssh...在多个主机上运行命令

相关内容