forまたはループを使用してホップサーバーのホストリストから「forループ」を実行するには?

forまたはループを使用してホップサーバーのホストリストから「forループ」を実行するには?

ホップサーバーからサーバーリストとして「forループ」を実行しようとしています。単一のサーバーでforループを実行するとうまくいきますが、ネストしてホップサーバーで動作させる方法を知りません。

各ホストのForループ出力:

$ for i in {a..b}; do echo Volume: /dev/sd$i; sudo /usr/sbin/smartctl -a /dev/sd$i | egrep -i "model|serial"; done
Volume: /dev/sda
Device Model:     TOSHIBA THNSNJ256GCSU
Serial Number:    35FS109IT88W
Volume: /dev/sdb
Model Family:     Seagate Constellation ES.3
Device Model:     ST4000NM0033-9ZM170
Serial Number:    Z1Z7EK85
$ 

以下は、通常、ホップサーバーで「forループ」を実行する方法です。

$ for i in `cat hostlist`;do echo $i;ssh $i "uptime";echo " ";done

提案してください!

答え1

似たようなものを探しているかもしれません。

while IFS= read -r host
do {
  printf "%s\n" "$host"
  ssh -t -- "$host" '
    for i in a b
    do
      printf "%s\n" "Volume: /dev/sd$i"
      sudo smartctl -a "/dev/sd$i" | grep -Ei "model|serial"
    done'
  } 0<&3
done 3<&0 <hostlist

hostlistホストが1行に1つずつファイルにリストされているとします。ホスト名には空白文字やバックスラッシュが含まれる可能性がないため、ここでは不要ですIFS=-rこの場合でも、ループからコンテンツをhostlist読み取ることは良いかもしれませんが、ループを使用することをお勧めします。バラよりforwhileスペースやその他の特殊文字が原因でシェルスクリプトが停止するのはなぜですか?これについて詳しく学んでください。

各ホストに対して、仮想端末をリモートホストに強制的に割り当てるオプションと一緒に呼び出され、sshパスワードの入力を求められます(そうでない場合)-tsudo

3<&0外部標準入力のファイル記述子をループ本文で使用できるようにコピーして新しいファイル記述子()を開きます({ }このため、ラップされます)。sshそうしないと、お客様の情報が読み取られ、hostlist当社はお客様と対話できなくなります(sudoパスワードが必要な場合など)。

私は後者であるのでechoに取り替えました。printfさらに堅牢になりました(ここでは必ずしも必要ではありませんが)。 (GNUマニュアルの確認)前者は廃止され、以前のバージョンとの互換性のためにのみ提供されるためにegrep置き換えられました。grep -E

最後に、中かっこ拡張()を{a..b}置き換えて、a bその機能をサポートしていない機能(たとえばdash)を含むすべてのPOSIXシェルでスクリプトを実行できるようにしました。

関連情報