-fオプションで開始されたSSHセッションを強制終了する方法(バックグラウンドで実行)


50

私はこれでかなり迷っています。manページから:

 -f      Requests ssh to go to background just before command execution.

-fオプションを使用してSSHを開始した後、トンネルが機能します。しかし、私はそれを使い終わった後、それとさらに相互作用する方法を知りません。たとえば、SSHトンネルを終了したときに閉じることができません

私が知っている通常の方法は機能しません。たとえば、jobs何も返しません。~コマンドが認識されない(と私はとにかく、それを使用する方法を正確に知りません)。

ただし、pgrepSSHトンネルがまだ実行されている(端末を閉じた後など)と表示されます。どうすればやり取りできますか?どうすれば閉じられますか?

回答:


65

スクリプトの特に良い解決策はmaster mode、制御コマンド用のソケットとともにを使用することです。

ssh -f -N -M -S <path-to-socket> -L <port>:<host>:<port> <server>

再び閉じるには:

ssh -S <path-to-socket> -O exit <server>

これにより、プロセスIDのgrepと、他のアプローチに関連するタイミングの問題の両方が回避されます。


10
初心者のために少し拡張するために、<path-to-socket>は、sshクライアントのマスターインスタンスが、マスターインスタンスの接続を共有する他のsshクライアントインスタンスとのプロセス間通信のために作成するファイルへのパスです。作成されたファイルは、実際にはUNIXドメインソケットを表します。これは、名前を付けて配置することができ何でも、あなたはそれは、例えば好きな場所/tmp/session1(それが使用してそれに名前を付けることが推奨されているが%のパターンを-見ControlPathの説明でman ssh_config
ゴーレム

1
また、コマンドの<server>部分にはssh -S <path-to-socket> -O exit <server>任意の文字列を使用できますが、存在する必要があります。それはちょっと不器用です。
ゴーレム

1
この答えと質問はやや古いですが、私がこれまで見たこの問題を処理する最もエレガントで「正しい」方法としてこれを支持したかったのです。ありがとうございます!
zentechinc

41

私はここで解決策を見つけました:http : //www.g-loaded.eu/2006/11/24/auto-closing-ssh-tunnels/

最善の方法-自動閉鎖するトンネル

前述のとおり、-f -Nスイッチの組み合わせを使用する代わりに、-fだけを使用するだけでなく、リモートマシンでコマンドを実行することもできます。しかし、トンネルを初期化するだけでよいので、どのコマンドを実行する必要がありますか?

これが、睡眠が最も有用なコマンドになるときです!この特定の状況では、睡眠には2つの利点があります。

  • 何もしないので、リソースは消費されません
  • ユーザーは実行時間を指定できます

これらがsshトンネルの自動クローズにどのように役立つかを以下に説明します。

リモートマシンでsleepコマンドを10秒間実行しながら、バックグラウンドでsshセッションを開始します。秒数は重要ではありません。同時に、以前とまったく同じようにvncviewerを実行します。

[me@local]$ ssh -f -L 25901:127.0.0.1:5901 me@remote.example.org sleep 10; \
          vncviewer 127.0.0.1:25901:1

この場合、sshクライアントは、sshセッションをバックグラウンドにフォーク(-f)し、トンネルを作成し(-L 25901:127.0.0.1:5901)、リモートサーバーでsleepコマンドを10秒間実行するように指示されます(sleep 10)。

この方法と以前の方法(-Nスイッチ)との違いは、基本的に、この場合sshクライアントの主な目標はトンネルを作成することではなく、10秒間スリープコマンドを実行することです。トンネルの作成は、副次的な目的である何らかの副作用です。vncviewerを使用しなかった場合、sshクライアントは10秒後に終了します。これは、実行するジョブがなくなるため、同時にトンネルを破壊するためです。

スリープコマンドの実行中に、別のプロセス(この場合はvncviewer)がそのトンネルの使用を開始し、10秒を超えて占有し続けると、sshクライアントがリモートジョブ(スリープの実行)を終了しても、別のプロセスがトンネルを占有しているため、終了します。言い換えると、sshクライアントはvncviewerも殺さなければならないため、トンネルを破壊できません。vncviewerがトンネルの使用を停止すると、すでに目標を達成したため、sshクライアントも終了します。

これにより、バックグラウンドで実行されているsshプロセスがなくなります。


4
簡単な発言/修正:私の知る限りvncviewer 127.0.0.1::25091、表示構文ではなくポート構文を使用していることを指定する必要があります。
クリスチャンウルフ

これは素晴らしいアイデアであり、Windowsで抱えていた問題をうまく回避します。Windowsの最近のバージョンにはsshクライアントが付属しており、理論的には-Sオプションをサポートしていますが、私にはうまくいかないようです。
キーリー

9

トンネルを強制終了するにはps -C sshps | grep sshまたはを使用して、トンネルを実行しているsshプロセスを特定します。その後、それを殺します。

または、このポートが開いているポートを判別して、プロセスを探すことができます。

netstat -lnpt | awk '$4 ~ /:1234$/ {sub(/\/.*/, "", $7); print $7}'

(ユーザーとして)マシン上で実行されているすべてのsshクライアントを強制終了する場合は、それを実行しますpkill ssh


6

ここで他の人が答えたように、pkill sshそれを殺します。

戻すことができるトンネルを作成するにscreenは、-fオプションなしで起動し、で画面をデタッチしますCtrl-A D。トンネルを戻すには、を呼び出しますscreen -r


ブルートフォース、しかし効果的
乳osis症

1
リモートで接続する場合は注意してください。pkill sshは、現在の接続も強制終了します。
ケニーート

@kennyutを使用するさらに別の理由screen
Haotian Yang

0

トンネルを開始するとき:

ssh -fN -D 8080 SOME_IP_HERE -l LOGIN_NAME_HERE
  • -f コマンド実行の直前にバックグラウンドに移動するようにsshに要求します。
  • -Nリモートコマンドを実行しないでください。これは、ポートを転送するだけの場合に便利です。
  • -D ローカルの「動的な」アプリケーションレベルのポート転送を指定します。
  • -l リモートマシンでログインするユーザーを指定します。

私はそれを閉じることができます:

ps -lef | grep ssh | grep "8080" | awk "{print \$2}" | xargs kill

-1

1つのコマンドラインですべてのトンネルを殺すために私が見つけた最良の解決策は

ps -lef|grep ssh|grep "\-L"|awk '{print $4}'|xargs kill

sshセッションの場合は、トンネルオプションを削除するだけです

ps -lef|grep ssh|awk '{print $4}'|xargs kill

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