sshが終了したときにsshによって生成されたプロセスを強制終了する


23

これは、ここだけでなく、スタック交換ネットワークの他のサイトでも何度か取り上げられた質問です(たとえば、sshを中断したときにリモートプロセスを強制終了するためにsshを作成する方法は? )。しかし、私はどのソリューションも私のために機能させることはできません。

sshを介してコマンドを実行しています。sshを終了するたびに、コマンドも停止するようにします。このコマンドはktserverと呼ばれるデーモンであり、Ctrl-Cを押すまで無期限に実行されます。

次のように実行します。ssh -t compute-0-1 ktserver実際、Ctrl-Cを押すと、プロセスは正常に終了し、sshセッションが終了します。

ただし、Ctrl-Cを押す代わりに、killコマンドを使用して(たとえば、SIGINTまたはSIGHUPを送信して)sshプロセスを強制終了すると、ktserverプロセスは存続します。

どうすれば殺さktserverれる方法に依存せずに常に死ぬことができsshますか?

編集:のktserverような完全に異なる何かを実行する代わりにgedit、すべてが魅力のように機能する場合(つまり、geditが接続が切れたときに死ぬ)。したがって、プロセス自体に何か問題がある可能性があります。たとえば、SIGHUPまたはSIGINTを無視しているのではないかと考えました。ただし、kill -1 ktserverまたはを実行するkill -2 ktserverと、プロセスは期待どおりに終了します。

EDIT2:Mark Plotnickが指摘しているように、この問題は、sshチャネルで循環している通信がないという事実に関連しています。ssh -t <host> readその後、sshプロセスを実行して終了することで確認しました。readまだ生きていて蹴っていました。


試しましたkill -9 ktserverか?

@HermanTorjussen確かに、それは動作します。問題は、このコマンドが別のプロセス内から実行されるため、プロセスが終了する可能性のある多くの可能性、したがってそのプロセスとのsshセッションを制御できない可能性があることです。そのため、プロセスがsshで終了するたびにktserverが死ぬことを確実にするための信頼できる方法が必要です。
GermanK

Linuxでの私の経験では、リモートコマンドがデッドtcp接続へのI / Oを行わない場合、実行し続けます。ネットワークの問題が原因で接続が切断されてからssh example.com dd ...数時間経っても、ジョブが完了するまで実行されましたsshktserver時々何かを出力するオプションをとるように変更できる場合、それは回避策かもしれません。
マークプロトニック

@MarkPlotnick確かreadに、リモートコンピューターで実行しようとしましたが、ssh接続を切断した後、read死ぬことはありませんでした。残念ながら、ktserverを変更して何も出力することはできません。それでは解決策はありませんか?
GermanK

2
sshが死んだとき、シェルも死んだと思います。シェルは、終了時にシグナル-1(SIGHUP)を送信するように構成できます。(shopt -s huponexit)。これがあなたのために働くかどうかテストできますか?
ヘネス

回答:


13

通常、ssh接続が終了すると、シェルも終了します。すべての子に対して終了するときにシグナル-1(SIGHUP)を送信するようにシェルを構成できます。

bashの場合、組み込みコマンドshoptを使用してこのオプションを構成できます。(shopt -s huponexit)。

zshが必要です。setoptHUP


これが私の現在の問題に対する答えだと思いましたが、うまくいかないようです。私は実行しています:ssh $ host "scp LargeFile.dat $ OtherHost:/ tmp"&pid = $!そして、次のコマンドでその転送を停止しようとします:shopt -s huponexit; kill $ pidですが、開始したsshを強制終了してもscpは停止しません。何かご意見は?
デビッドドリア14年

scpコマンドを開始する前にシェルオプションを設定してテストできますか?または、シェルを起動し、shoptを設定してscpを起動しますか?
ヘネス14年

2
これは私にとってはうまくいきますが、まずptyではなく、ttyの割り当てを強制するを使用していることを確認する必要がssh -t -tあります(-t2回注意してください!)。
ニコラスウー14

13

私はそれを機能-t -tさせるための引数として単に使用していることがわかりましたsshhuponexit元のシェルまたはリモートシェルに設定する必要はありませんでした。

これを次のようにテストしました。

動作しません:

ssh user@remote sleep 100
^C

これによりsshセッションが強制終了されましたが、リモートホストでスリーププロセスがまだ実行されていることがわかります(ps -ef | grep sleep表示されています)。

動作します:

ssh -t -t user@remote sleep 100
^C

これによりsshセッションが強制終了され、リモートスリーププロセスも強制終了されました。また、- SIGINTを使用した場合、リモートプロセスに送信されるシグナルが-であることも確認しました。また、プロセスにSIGKILL(-9)を適用すると、リモートプロセスも強制終了されることを確認しました。ControlCssh

編集1:

それsleep ... 当てはまりました。より頑固なリモートプロセスの場合、ssh^ Cの処理がSIGINTとは異なることがわかりました。Ctrl- C働きましたが、しませkill -INT $pidんでした。

これが、実際のアプリケーション(他の回答から盗み出す)で機能するようになったものです。

ssh -t -t -i id_rsa user@mic0 "/bin/sh -O huponexit -c 'sleep 100'"

二重引用符と単一引用符のネストされた使用に注意してください。リモートプロセスは、実際に終了することでSIGHUPに応答する必要があることに注意してください!


これは私には最適でしたが、参考までに、端末制御文字がにじみ出て、面白い出力を引き起こす可能性がありました。したがって、私の場合の簡単な回避策は、呼び出されたコマンドをラップし、その出力をでパイプすることcatでした。たとえば、ssh -ttq user@host '{ cmd; cmd; } | cat'
Droj

Ctrl-C常に同等ではありませんkill -INT $pid、上の私の答えを参照してくださいunix.stackexchange.com/questions/377191/...に、別のstackoverflow.com/questions/8398845/... ;-)血みどろの詳細については、
thecarpy

@thecarpy-最初の答えはCtrl-CがSIGINT似ていると言い、他の答えは^CSIGINTを送ると言います。それで、それらが同等でない場合の正確な違いは何ですか?
マークラカタ

1

sshが信号を伝搬しない場合、sshはそれから何を期待しますか?

UPD。(JosephRに特化):それは明らかに誤解から生じる問題自体のエラーです-「sshが死んだときにsshによって生成されるプロセスを殺す」。SSHは通常、プロセスを生成しません(時には生成しますが、これは別の話です)、代わりに接続の反対側を見るとSSHDが生成します。SSHは、リモートサーバーが持つ擬似端末抽象化に依存するだけです。それが助けになる唯一のことは、接続されたプロセスに信号を発信する端末の能力があるという理由です。これは、すべてのUNIXライクなシステムにとって非常に基本的なものです。


1
これは質問に対する答えを提供しません。著者に批判や説明を求めるには、投稿の下にコメントを残してください。
アントン

@アンソン、それは説明です。しかし、これが唯一の正しい答えであると述べている人はいません。以下のコメントをありがとう。
poige

1
@poigeおそらく説明を具体化して、OPや他の人たちに役立つようにしましょう。
ジョセフR.

@JosephR。、わかりました、あなただけのために。
poige

1
「ssh接続が失われたときにsshdによって生成されたプロセスを殺す」と言ったら、あなたにとっては良いと思いますか?言い換えることで私の問題が解決されるとは思いません。
GermanK

0

ここに投稿された解決策は私にはうまくいきませんでしたが、同様の問題の解決策を探していたときに最初にこの質問が出てきたので、-t -tここでトリックが言及されたので、他の人が試してみた解決策を投稿します。

ssh -t -t -o ControlMaster=auto -o ControlPath='~/test.ssh' your_remote_ip_goes_here "your_long_running_command" &
sleep 100
ssh -o ControlPath='~/test.ssh' -O exit your_remote_ip_goes_here

このように接続が終了すると、長時間実行しているコマンドは実行されなくなりました。

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