如何终止以-f选项启动的SSH会话(在后台运行)


49

我对此很迷茫。从手册页:

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

使用该-f选项启动SSH后,我的隧道可以正常工作。但是,在我使用完它之后,我不知道如何进一步与它交互。例如,完成后无法关闭SSH隧道

我知道的通常方法不起作用。例如,jobs什么也不返回。该~命令无法识别(无论如何,我也不知道确切如何使用它)。

但是,pgrep告诉我SSH隧道仍在运行(在关闭终端等之后)。我如何与之互动?我该如何关闭?

Answers:


64

一个特别好的脚本解决方案是使用master mode,带有用于控制命令的套接字:

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

要再次关闭它:

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

这样既避免了重复获取进程ID,也避免了可能与其他方法相关联的任何时序问题。


10
只是为了使未启动的扩展一点,<path-to-socket>是ssh客户端的主实例将创建的文件路径,用于与希望共享主实例连接的其他ssh客户端实例进行进程间通信。创建的文件实际上将代表一个Unix域套接字。可以在任意位置进行命名和定位,例如/tmp/session1(尽管建议使用模式命名-参见参考中的ControlPath描述man ssh_config
golem

1
同样,该命令的<server>部分ssh -S <path-to-socket> -O exit <server>可以是任何字符串,但是必须存在。有点笨拙。
lem 2015年

1
这个答案和问题有些陈旧,但是我想认可这可能是解决我所看到的这个问题的最优雅,最“正确”的方式。谢谢你,先生!
zentechinc

41

我在这里找到了解决方案:http : //www.g-loaded.eu/2006/11/24/auto-closing-ssh-tunnels/

最好的方法-自动关闭的隧道

如前所述,除了使用-f -N开关组合之外,我们还可以仅使用-f,还可以在远程计算机上执行命令。但是,由于只需要初始化隧道,应该执行哪个命令?

这是睡眠可以成为所有命令中最有用的命令!在这种特殊情况下,睡眠有两个优点:

  • 它什么都不做,所以没有资源消耗
  • 用户可以指定执行多长时间

下面介绍了这些方法如何自动关闭ssh隧道。

我们在后台启动ssh会话,同时在远程计算机上执行sleep命令10秒钟。秒数不是至关重要的。同时,我们完全像以前一样执行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秒后退出,因为它将没有更多的工作要做,同时破坏了隧道。

在执行sleep命令期间,如果另一个进程(在这种情况下为vncviewer)开始使用该隧道并将其占用的时间超过10秒,那么即使ssh客户端完成了其远程作业(执行睡眠),它也无法退出,因为另一个进程占用了隧道。换句话说,ssh客户端无法销毁隧道,因为它也必须杀死vncviewer。当vncviewer停止使用隧道时,ssh客户端也会退出,因为它已经完成了其目标。

这样,就不会在后台运行任何ssh进程。


4
简短说明/更正:据我所知,您必须vncviewer 127.0.0.1::25091使用端口语法而不是显示语法进行指定。
Christian Wolf

这是一个好主意,可以巧妙地回避我在Windows上遇到的问题。Windows的最新版本附带了ssh客户端,理论上它支持-S选项,但似乎对我不起作用。
Keeely

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


蛮力,但有效
母权主义

1
请注意是否要远程连接。pkill ssh甚至会终止您当前的连接。
kennyut

@kennyut使用的另一个原因screen
杨昊天

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

我发现在一个命令行中杀死所有隧道的最佳解决方案是

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

对于ssh会话,只需删除隧道选项

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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.