ループ中にbashでリモートlsを実行中に問題が発生しました。

ループ中にbashでリモートlsを実行中に問題が発生しました。

単一の BASH ステートメントで次の操作を実行する必要があります。好ましくは、4つのシステムをA、B、C、Dと呼ぶ。

システム A は SSH を介してシステム B およびシステム C に接続できます。

システム B は SSH を介してシステム D に接続できます。

システムAで次のコマンドを実行します。

ssh systemB "cd folder && (while true; do val1=\$(ssh systemD 'ls directory' | wc -l); val2=$(ssh systemC 'ls directory' | wc -l); echo "\$val1 \$val2"; if (( val1 == 0 && val2 == 0 )); then echo "Done"; break; fi; sleep 5; done;)"

ループが最初に実行されたときに正しいファイル数を取得するようです。ループの開始後に両方のディレクトリのファイル数が変更されるとval1、値はval2変わりません。

答え1

そうでsystemBなければ、そこsshsystemCループを持つことはできません。以下で駆動する必要がありますsystemA

until
  val1=$(ssh -J systemB systemD "ls -q directory | wc -l")
  val2=$(ssh systemC "ls -q directory | wc -l")
  echo "$val1  $val2"
  [ "$val1" -eq 0 ] && [ "$val2" -eq 0 ]
do
  sleep 5
done
echo Done

返品:

  • さらに、ファイル名なしで改行を数えることもできます-qls数値がゼロでないことを確認することであれば、ここでは実際には問題になりません。
  • wc -lファイル全体のリストを転送したくない場合は、リモートでカウント()します。
  • 終了条件が何であるかをより明確に説明します。
  • として-J systemB使用systemB飛躍マスター。認証は依然としてsystemC資格情報(Sshエージェントまたはキー)を使用して実行されます。 'をsystemA使用するには、以下を実行してください。systemBssh systemB 'ssh systemD "ls -q directory | wc -l"'

ファイル数を計算する代わりに、最初の一致で停止するためにwhichを使用することができ、ls | grep -q '^'systemDにファイルがある場合はsystemCへのsshingを避けることもできます。

while
  ssh -J systemB systemD "ls -U directory | grep -q \^" ||
    ssh systemC "ls -U directory | grep -q \^"
do
  sleep 5
done
echo Done

(GNUにソートをスキップするオプションがlsあると仮定すると、これはディレクトリからファイル名を読み取ると出力を開始できることを意味します)-Uls

SSH制御ソケットを使用すると、実行するたびに高価なSSH接続と認証を回避できます。

答え2

1行のコードではなく、次のようなコードを書くとすぐに問題を確認できます。

ssh systemB "cd folder &&
            (while true; do
                val1=\$(ssh systemD 'ls directory' | wc -l); 
                val2=$(ssh systemC 'ls directory' | wc -l); 
                echo "\$val1  \$val2"; 
                if (( val1 == 0 && val2 == 0 )); then 
                    echo "Done"; 
                    break; 
               fi; 
               sleep 5; 
            done;)"

あなたは行から\欠落しています。したがって、ループの一部ではなく完了時に生成されます。$val2val2ssh systemB

したがって、このコマンドを開始したときに$(ssh systemC 'ls directory' | wc -l)値が10の場合、ループは次のようになります。

ssh systemB "cd folder &&
            (while true; do
                val1=\$(ssh systemD 'ls directory' | wc -l); 
                val2=10; 
                echo "\$val1  \$val2"; 
                if (( val1 == 0 && val2 == 0 )); then 
                    echo "Done"; 
                    break; 
               fi; 
               sleep 5; 
            done;)"

関連情報