web-dev-qa-db-ja.com

SSH -tがバックグラウンドプロセスを待たないのはなぜですか?

ssh -tがバックグラウンドジョブの完了を待たないのはなぜですか?

例:

ssh user@example 'sleep 2 &'

Sshは2秒後に戻るため、これは期待どおりに機能しますが、

ssh user@example -t 'sleep 2 &'

sleepが完了するのを待たずに、すぐに戻ります。

誰かがこの背後にある理由を説明できますか?戻る前に、すべてのバックグラウンドプロセスが完了するのをssh -tに待機させる方法はありますか?

私の使用例は、ssh -tでスクリプトを開始することです。このスクリプトは、メインスクリプトの終了後も存続する必要があるいくつかのバックグラウンドジョブを開始します。 ssh -tでは、これは今のところ不可能です。

13
Philipp Murry

-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を受信します(デフォルトではプロセスが終了します)。

22

waitを使用:

ssh user@example -t 'sleep 2 & wait'
5
Ipor Sircer