SSHを使用して、for
ループ内の複数のリモートマシンでいくつかのコマンドを実行します。 IPアドレスのリストに対して同じコマンドを実行します。一部のIPアドレスは到達できない可能性があるため、ConnectTimeout
オプションを使用しました。
しかし、私のスクリプトは思い通りに機能しませんでした。実際には、リストの次のIPアドレスをあきらめて試行するのではなく、最初の到達不能IPでスタックしました。
これが私のスクリプトの関連部分です:
for ip in ${IP} ; do
ssh -o BatchMode=yes \
-o StrictHostKeyChecking=no \
-o ConnectTimeout=10 \
-l ${USERNAME} \
${SCRIPT_Host} \
"${COMMAND} -i $ip || echo timeout" \
>> ./myscript.out
done
到達可能なIPでは問題なく機能しますが、特定のIPがダウンしている場合はしばらく待機し(10秒を超える、おそらく35〜40秒)、端末にエラーメッセージを表示します。
ERROR connecting : Connection timed out
だから私は私が正しく使用しなかったオプションを疑問に思っています。
ConnectTimeout
の使用は正しいので、30秒以上後にタイムアウトする理由は明らかではありません。
タイムアウトの問題を完全に回避するためにスクリプトを変更する方法は次のとおりです。
parallel
を使用して、同時に複数の宛先ホストに接続します。-f
オプションを使用して、バックグラウンドで処理します。GNU parallelを使用したソリューションで、最大50の接続を同時に実行します。
parallel --gnu --bg --jobs 50 \
ssh -o BatchMode=yes \
-o StrictHostKeyChecking=no \
-o ConnectTimeout=10 \
-l ${USERNAME} \
{} \
"${COMMAND} -i {} || echo timeout" \
::: ${IP}
parallel <command> ::: <arguments>
は、<command> <argument>
リストを分割することにより、<arguments>
を並列で何度も実行します。 <argument>
のプレースホルダーは{}
です。
parallel --jobs n
を使用して、並列接続の数を制限します。
接続タイムアウトは、すでに接続を確立していて、接続がその秒数の間アイドル状態のままである場合、切断されます(つまり、接続の確立を妨げるKEEP_ALIVE sshパラメータもアクティブにしていない場合)アイドル)。
タイムアウトが発生するまでに30秒以上かかる理由は、TCPプロトコル内部タイマーがその時間接続しようとし、接続できないというエラーメッセージを返すためです。 sftpサーバーです。sshからではありません。