如何终止后台的ssh实例
问题描述:
我已经编写了C程序,它使用fork(2)和execl(3)为端口转发目的运行ssh。 ssh在后台运行-f选项。如何终止后台的ssh实例
当C程序退出时,我希望它发送SIGTERM到它生成的ssh实例。
我已经试过
// creating the ssh process
ssh_pid = fork();
if (ssh_pid == 0)
execl("/usr/bin/ssh", "/usr/bin/ssh", "-f", other options, NULL)
// ...
printf("Killing %d\n", ssh_pid); // <--- output the PID
kill(ssh_pid, 15);
sleep(1); // give it a chance to exit properly
if (kill(ssh_pid, 0) == 0)
kill(ssh_pid, 9); // the "shotgun" approach
然而,这并没有(甚至与SIGKILL)工作。
如果我运行PS 程序退出
ps aux | grep ssh | grep -v sshd | grep -v grep
之前,我看到这样的事情:
user 27825 0.2 0.0 0 0 pts/0 Z+ 18:23 0:00 [ssh] <defunct>
user 27834 0.0 0.0 41452 1176 ? Ss 18:23 0:00 /usr/bin/ssh -f [other options]
当程序打印它杀死PID,我看到:
Killing 27825
随后重复ps给我:
user 27834 0.0 0.0 41452 1176 ? Ss 18:23 0:00 /usr/bin/ssh -f [other options]
看起来原来的ssh已经为了成为后台进程而分叉了。
所以我改变了我的电话杀(2)试图杀死由原始的SSH产生的所有进程:
kill(-ssh_pid, 15);
但是这似乎没有任何效果。我怀疑这是因为原来的ssh不再是背景音乐ssh的父母。
那么,我该如何安全地杀死背景的ssh?它甚至有可能吗?
答
我刚刚找到的解决方案并不是全部使用-f选项,而是自己背景ssh。
ssh_pid = fork();
if (ssh_pid == 0)
{
freopen("/dev/null", "r", stdin);
freopen("/dev/null", "w", stdout);
freopen("/dev/null", "w", stderr);
execl("/usr/bin/ssh", "/usr/bin/ssh", other options, NULL);
}
因为当ssh获得-f选项时它会创建一个子对象,并且发送给父对象的信号不会传递给子对象。
我决定使用[libssh2](http://www.libssh2.org/)而不是执行大量的ssh(1)进程。 – szmoore 2013-02-19 08:11:58
我认为更好的解决方案是使用SSH的“ControlMaster”功能。我回答了一个类似的问题[这里](http://*.com/a/26470428/1072112)。 – ghoti 2015-08-18 04:12:38