我编写了使用 fork(2) 和 execl(3) 运行 ssh 以进行端口转发的 C 程序。ssh 在后台运行 -f 选项。
当 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 为了成为后台进程已经分叉了自己。
所以我改变了对 kill(2) 的调用,试图杀死原始 ssh 产生的所有进程:
kill(-ssh_pid, 15);
但这似乎没有效果。我怀疑这是因为原始 ssh 不再是后台 ssh 的父级。
那么,如何安全地杀死后台 ssh?甚至可能吗?