ssh死后,ssh产生的终止进程


23

这个问题不仅在这里而且还在堆栈交换网络的其他站点中都已多次解决(例如,当我中断ssh本身时,如何使ssh杀死远程进程? )。但是,我无法使任何解决方案对我有用。

我正在通过ssh运行命令。每当我退出ssh时,我都希望命令也消失。此命令是一个名为ktserver的守护程序,它将无限期运行,直到您按Ctrl-C为止。

我按如下方式运行它:ssh -t compute-0-1 ktserver实际上,当我按Ctrl-C时,该过程正常结束,ssh会话结束。

但是,如果我不使用Ctrl-C而是使用kill命令杀死ssh进程(例如,发送SIGINT或SIGHUP),则该ktserver进程仍然有效。

我该如何使ktserver永远死亡独立于如何ssh被杀?

编辑:如果不是代替ktserver我运行完全不同的操作(例如)gedit,那么一切都像超级按钮一样工作(即,当连接断开时,gedit断开)。因此,流程本身可能有问题。例如,我认为它可能会忽略SIGHUP或SIGINT。但是,当我运行kill -1 ktserver或时kill -2 ktserver,该过程按预期方式终止。

编辑2:正如Mark Plotnick所指出的那样,问题与ssh通道上没有通信流通这一事实有关。我已经通过运行ssh -t <host> read并终止ssh进程来确认。read还活着,踢着。


你试过了kill -9 ktserver吗?

@HermanTorjussen当然可以。问题是该命令是在另一个进程中运行的,我可能无法控制可能导致进程死亡的所有可能性,因此无法与之进行ssh会话。因此,我需要一种可靠的方法来确保每当我的进程(以及因此出现),ktserver都将与它们一同消失。
GermanK 2013年

我在Linux上的经验是,如果远程命令不对死掉的tcp连接进行任何I / O操作,它将继续运行。由于网络问题,ssh example.com dd ...即使在ssh连接断开后的几个小时,我的工作也已完成。如果您可以更改ktserver以选择不定期输出某些内容,则可能是一种解决方法。
Mark Plotnick

@MarkPlotnick确实,我已经尝试read在远程计算机上运行,并且在终止ssh连接read后没有消失。不幸的是,我无法将ktserver更改为输出任何内容。那有没有解决办法呢?
GermanK 2013年

2
我假设ssh死亡时,您的shell也将死亡。您可以将外壳配置为在终止时发送信号-1(SIGHUP)。(shopt -s huponexit)。您可以测试一下是否适合您吗?
Hennes

Answers:


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不会停止。有什么想法吗?
David Doria 2014年

您可以启动scp命令之前测试一下设置的shell选项吗?还是通过启动shell,设置shopt并启动scp?
Hennes 2014年

2
这对我有用,但是我必须首先确保使用ssh -t -t,(-t两次注意!),这会强制tty分配,而不仅仅是pty。
Nicolas Wu

13

我发现只是将其-t -t用作ssh使它工作的参数。我不必设置huponexit为原始外壳程序或远程外壳程序。

我对此进行了如下测试:

不起作用:

ssh user@remote sleep 100
^C

这杀死了ssh会话,但是我可以看到睡眠进程仍在远程主机上运行(ps -ef | grep sleep显示它)。

可以工作:

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

这将杀死ssh会话,并且远程睡眠过程也将被终止。我还验证了发送到远程进程的信号SIGINT是否使用Control- C。我还验证了应用于该ssh进程的SIGKILL(-9)也会杀死远程进程。

编辑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,另一个答案说^C发送SIGINT。那么,如果它们不相等,确切的区别是什么?
Mark Lakata '17

1

如果ssh不传播信号,它将收到您期望的信号吗?

UPD。(特别适用于JosephR):这显然是一个错误本身,是由于误解而引起的-“当ssh死亡时ssh产生的杀死进程”。当我们查看连接的另一面时,SSH通常不会生成进程(有时会生成,但这是另一回事),而SSHD会生成。SSH仅依赖于远程服务器具有的伪终端抽象。这就是为什么唯一可以提供帮助的是终端能够向其附属进程发出信号的能力。对于每个类似UNIX的系统来说,这是非常基本的。


1
这不能为问题提供答案。要批评或要求作者澄清,请在其帖子下方发表评论。
Anthon 2013年

@Anthon,这是一个解释。但是没有人说这应该是唯一正确的答案。感谢您在下面的评论。
poige 2013年

1
@poige也许会充实说明,以便它对OP和其他人员有用。
约瑟夫

@JosephR。,好的,只为您。
poige

1
如果我说“当ssh连接断开时杀死由sshd产生的进程”对您来说听起来会更好吗?我认为改名不会以任何方式解决我的问题。
GermanK 2013年

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

这样终止连接后,我的长时间运行的命令不再运行。

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.