ホップサーバーからサーバーリストとして「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
読み取ることは良いかもしれませんが、ループを使用することをお勧めします。バラよりfor
while
スペースやその他の特殊文字が原因でシェルスクリプトが停止するのはなぜですか?これについて詳しく学んでください。
各ホストに対して、仮想端末をリモートホストに強制的に割り当てるオプションと一緒に呼び出され、ssh
パスワードの入力を求められます(そうでない場合)-t
sudo
3<&0
外部標準入力のファイル記述子をループ本文で使用できるようにコピーして新しいファイル記述子()を開きます({
}
このため、ラップされます)。ssh
そうしないと、お客様の情報が読み取られ、hostlist
当社はお客様と対話できなくなります(sudo
パスワードが必要な場合など)。
私は後者であるのでecho
に取り替えました。printf
さらに堅牢になりました(ここでは必ずしも必要ではありませんが)。 (GNUマニュアルの確認)前者は廃止され、以前のバージョンとの互換性のためにのみ提供されるためにegrep
置き換えられました。grep -E
最後に、中かっこ拡張()を{a..b}
置き換えて、a b
その機能をサポートしていない機能(たとえばdash
)を含むすべてのPOSIXシェルでスクリプトを実行できるようにしました。