単一の 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
なければ、そこssh
にsystemC
ループを持つことはできません。以下で駆動する必要があります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
返品:
- さらに、ファイル名なしで改行を数えることもできます
-q
。ls
数値がゼロでないことを確認することであれば、ここでは実際には問題になりません。 wc -l
ファイル全体のリストを転送したくない場合は、リモートでカウント()します。- 終了条件が何であるかをより明確に説明します。
- として
-J systemB
使用systemB
飛躍マスター。認証は依然としてsystemC
資格情報(Sshエージェントまたはキー)を使用して実行されます。 'をsystemA
使用するには、以下を実行してください。systemB
ssh 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
あると仮定すると、これはディレクトリからファイル名を読み取ると出力を開始できることを意味します)-U
ls
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;)"
あなたは行から\
欠落しています。したがって、ループの一部ではなく完了時に生成されます。$
val2
val2
ssh 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;)"