ssh -t
がバックグラウンドジョブの完了を待たないのはなぜですか?
例:
ssh user@example 'sleep 2 &'
Sshは2秒後に戻るため、これは期待どおりに機能しますが、
ssh user@example -t 'sleep 2 &'
sleep
が完了するのを待たずに、すぐに戻ります。
誰かがこの背後にある理由を説明できますか?戻る前に、すべてのバックグラウンドプロセスが完了するのをssh -t
に待機させる方法はありますか?
私の使用例は、ssh -t
でスクリプトを開始することです。このスクリプトは、メインスクリプトの終了後も存続する必要があるいくつかのバックグラウンドジョブを開始します。 ssh -t
では、これは今のところ不可能です。
-t
がない場合、sshd
は2つのパイプを介してリモートシェル(およびsleep
のような子)とstderrのstdoutを取得します(別のパイプを介してクライアントの入力も送信します)。
sshd
は、ユーザーのログインシェルを開始したプロセスを待機しますが、そのプロセスが終了した後、stdoutパイプ(少なくともopensshの場合はstderrパイプではない)でeofを待機します。
Eofは、パイプの書き込み側で開かれているプロセスによってファイル記述子がない場合に発生します。これは通常、stdoutを他にリダイレクトしていないすべてのプロセスがなくなった場合にのみ発生します。
-t
を使用する場合、sshd
はパイプを使用しません。代わりに、リモートシェルおよびその子とのすべての対話(stdin、stdout、stderr)は、1つの擬似端末ペアを使用して行われます。
疑似端末ペアでは、sshd
がマスター側と対話するため、同様のeof処理や、疑似端末のスレーブ側に開いているfdsのプロセスがまだあるかどうかを確認する方法がないため、リモートユーザーのログインシェルを実行したプロセスの終了を待って終了します。
その終了時に、ptyペアのマスター側が閉じられます。つまり、ptyが破棄されるため、スレーブによって制御されるプロセスはSIGHUPを受信します(デフォルトではプロセスが終了します)。
wait
を使用:
ssh user@example -t 'sleep 2 & wait'