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


13

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

例:

ssh user@example 'sleep 2 &'

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

ssh user@example -t 'sleep 2 &'

sleep終了するのを待たずにすぐに戻ります。

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

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

回答:


22

なしで-t、2つのパイプを介しsshdてリモートシェル(およびのような子sleep)とstderr の標準出力を取得します(また、別のパイプを介してクライアントの入力を送信します)。

sshd ユーザーのログインシェルを開始したプロセスを待機しますが、そのプロセスが終了した後、stdoutパイプ(少なくともopensshの場合はstderrパイプではない)でeofを待機します。

また、eofは、パイプの書き込み側で開いているプロセスによってファイル記述子が存在しない場合に発生します。これは通常、stdoutが他の場所にリダイレクトされていないすべてのプロセスがなくなった場合にのみ発生します。

を使用する場合-tsshdパイプは使用しません。代わりに、リモートシェルとその子とのすべての対話(stdin、stdout、stderr)は、1つの擬似端末ペアを使用して行われます。

擬似端末のペアではsshd、マスター側と対話するために、同様のeof処理や、擬似端末のスレーブ側に開かれたfdsのプロセスがまだあるかどうかを知る方法はないため、リモートユーザーのログインシェルを実行して終了するプロセス。

その終了時に、ptyペアのマスター側が閉じられ、ptyが破棄されるため、スレーブによって制御されるプロセスはSIGHUPを受け取ります(デフォルトでは終了します)。


1
徹底的な回答をありがとう!私が知りたいもう一つのこと:すべてのバックグラウンドプロセスは、擬似端末が終了すると終了しますか?私が開始しているスクリプトは、sshでうまく機能するサービスを開始します。ただし、ssh -tを使用すると、サービスは開始されません。sshが戻ると、サービスはシャットダウンされるようです。
フィリップマリー

実際には、擬似端末のマスター側が、すべてのスレーブファイル記述子が閉じられたことを知る方法があります。実際には、それに対するすべてのファイル記述子が閉じられたときに、実際の端末によってトリガーされる同じメカニズムです。
JdeBP


@JdeBP、拡大しますか?どういう意味かわかりません。AFAICT端末エミュレータ(少なくともxtermのとGNOME端末)プロセスがまだプロセスは、それらがダイにシェルを実行したときにスレーブに開口FDSを有する気にしない
ステファンChazelas

@PhilippMurryを使用nohupして、そのようなスクリプトを実行し続けることができます。(内部で実行時間の長いジョブを開始することを検討することもtmuxできます。その場合、進行状況をインタラクティブに監視できますが、ログファイルは正常に機能します。)
jpaugh

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.