複数のSSHコマンドを並列に実行し、出力を変数に格納する方法

複数のSSHコマンドを並列に実行し、出力を変数に格納する方法

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

バックグラウンドジョブはサブシェルで実行されるため、コマンドの置換にかかわらず、バックグラウンドで変数の割り当てを有効に使用できないと思います。例えば

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

xサブシェルに対してのみ2番目の割り当てを印刷します。

一方、コマンドオーバーライド内でバックグラウンドで実行すると、目的のタスクは実行されず、シェルはとにかくコマンドを待ち、タスクを順番に実行します。

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複数のホストでコマンドを実行するための既製のソリューションはたくさんありますが...

おすすめ記事