我需要运行一个子进程,执行一些代码,然后终止已启动的进程;我不需要这个子流程的输出。我试过这样的事情:
def start
@@rtorrentIO ||= IO.popen("rtorrent")
sleep 0.5
end
def stop
Process.kill(9, @@rtorrentIO.pid) if defined? @@rtorrentIO
@@rtorrentIO = nil
end
start
sleep 0.5
#some code there
stop
但是终端对我所做的任何动作都没有反应(甚至 Ctrl + C 转义)。我做错了什么?
更新 我在初始条件下犯了一个小错误。实际上终端会对我的所有操作做出反应,但在命令执行之前我没有看到任何符号。在下图中,我始终执行以下命令:mangaParser.rb;我是谁; PS; 这就是我得出的结果:
但是,如果我尝试用 Ctrl + C 转义来破坏运行命令,那就失败了(例如,如果没有,我就不能打破以下命令序列其他终端:mangaParser.rb; ping google.com;)
答案 0 :(得分:1)
如果我将其更改为
#!/usr/bin/env ruby
def start
@rtorrentIO ||= IO.popen("rtorrent",'w') #default mode is 'r'
sleep 0.5
end
def stop
Process.kill(9, @rtorrentIO.pid) if defined? @rtorrentIO
@rtorrentIO = nil
end
start
sleep 0.5
#some code there
stop
使它成为一个独立的例子,它对我来说很好。您应该打开用于撰写(..,"w")
的管道,因为您对输出不感兴趣(如果您对编写它不感兴趣,那么打开它是没有意义的使用popen
进行处理,并且您最好使用pid = Process.spawn('rtorrent')
之类的内容。
<强>更新强>
您遇到的问题是rtorrent
通过在输出中写入特殊的终端控制序列(有意或无意)来弄乱您的终端。这种情况会不时发生(cat
随机二进制文件很可能会弄乱您的终端,因为您可能会遇到一个对终端有点特殊的字节序列) 。解决方案是在终端中运行reset
(有关详情,请参阅man reset
) - 您必须盲目输入。
如果您不希望rtorrent
这样做,重定向其 stdout 和 stderr (这些通常绑定到您的终端)将是最重要的可能会阻止它写入您的终端。除此之外,您可以使用system reset
方法stop
来修复rtorrent
所做的事情。
以下是上述内容的组合:
#!/usr/bin/env ruby
def start
@pid ||= Process.spawn "rtorrent" #, err: '/dev/null', out: '/dev/null'
sleep 0.5
end
def stop
Process.kill(9, @pid) if @pid
@pid = nil
system 'reset'
end
start
sleep 0.5
#some code there
stop