だからscriptAがあり、その役割は次のとおりです。
ssh server1 -- scriptB &
ssh server2 -- scriptB &
ssh server3 -- scriptB &
wait
otherstuffhappens
ScriptBの機能は次のとおりです。
rsync -av /important/stuff/. remoteserver:/remote/dir/.
rsync -av /not/so/important/stuff/. remoteserver:/remote/dir/. &
exit
私が望む結果は、scriptAが続行する前にscriptBのすべてのインスタンスが完了するのを待つことです。現在はそうしていますが、それほど重要ではない項目のバックグラウンドrsyncも待っています。このファイルは大きいので、待ちたくありません。
私はすべて読んだnohup、disown、&の違いいろいろな組み合わせを試してみましたが、目的の結果が得られませんでした。
この時点で私は混乱しています。どんな助けでも大変感謝します!
ベストアンサー1
ここでの問題は、sshd
コマンドのstdoutを読み取るパイプのファイルの終わりを待つことです(少なくともテスト中のバージョンでは何らかの理由でstderrの代わりに)。そしてバックグラウンドジョブはパイプラインのfdを継承します。
したがって、この問題を解決するには、バックグラウンド コマンドの出力を一部のファイルにrsync
リダイレクトしたり、/dev/null
気にしないようにしてください。また、stderrをリダイレクトする必要があります。 sshdがそのパイプを待たなくてもsshd
終了後にパイプが破壊されるので、rsync
stderrに書き込もうとするとパイプが終了するからです。
だから:
rsync ... > /dev/null 2>&1 &
比較する:
$ time ssh localhost 'sleep 2 &'
ssh localhost 'sleep 2 &' 0.05s user 0.00s system 2% cpu 2.365 total
$ time ssh localhost 'sleep 2 > /dev/null &'
ssh localhost 'sleep 2 > /dev/null &' 0.04s user 0.00s system 12% cpu 0.349 total
そして:
$ ssh localhost '(sleep 1; ls /x; echo "$?" > out) > /dev/null &'; sleep 2; cat out
141 # ls by killed with SIGPIPE upon writing the error message
$ ssh localhost '(sleep 1; ls /x; echo "$?" > out) > /dev/null 2>&1 &'; sleep 2; cat out
2 # ls exited normally after writing the error on /dev/null instead
# of a broken pipe