使用PTY.spawn打开Ruby kill虚拟shell

时间:2011-06-10 18:56:34

标签: ruby linux process kill pty

在ruby脚本中,我启动了更多虚拟shell,每个shell都由shell管理器对象管理,如下所示:

@shell = PTY.spawn 'env PS1="\w>" TERM=dumb COLUMNS=63 LINES=21 sh -i'

在稍后的某个时间点,我想销毁这个实例并杀死相关的shell进程。可悲的是,我无法正常工作。这是我尝试的,按照概率起作用:

  • 没有什么,也就是说,当管理对象被破坏时,期望shell proc被关闭。
  • 使用kill命令终止在shell上运行的所有进程(这都有效),然后使用system("kill #{@shell[2]")终止shell本身。这没有效果。
  • 在上面使用-9。这使shell进程失效。

当ruby程序退出时,所有shell都会关闭,但我想在保持程序运行的同时杀死它们。有没有人遇到过这样的事情?

1 个答案:

答案 0 :(得分:4)

问题是僵尸。是的,真的。

所有Unix风格的内核都会离开这个进程,直到有人等待它为止。 (这是为了跟踪PID,退出状态和其他一些东西。)它们被称为僵尸并且在ps(1)列表中具有Z状态。你无法杀死他们,因为他们已经死了。当你等待它们时它们会消失。

以下是如何清理@shell对象:

@shell[0].close
@shell[1].close
begin
  Process.wait @shell[2]
rescue PTY::ChildExited
end

您可能不需要救援区块,具体取决于您是否有更高级别的图层过于广泛地捕获异常。 (叹气,就像我的irb。)

顺便说一下,当Ruby程序退出时你的进程最终消失的原因是因为僵尸也变成了一个孤儿(没有父进程),shell或init(8)最终都会等待所有的孤儿。