我正在使用命令行程序,它的工作原理如下:
$ ROUTE_TO_FOLDER/app < "long text"
如果“长文字”是使用“app”需要的参数编写的,那么它会填充带有结果的文本文件。如果没有,它将连续填充文本文件中的点(我无法处理或修改“app”的代码以避免这种情况)。
在ruby脚本中有一行如下:
text = "long text that will be used by app"
output = system("ROUTE_TO_FOLDER/app < #{text}")
现在,如果文字写得很好,就不会有问题,我会得到一个如前所述的输出文件。文本写得不好时会出现问题。接下来发生的事情是我的ruby脚本挂起,我不知道如何杀死它。
我找到Open3并且我使用了这样的方法:
irb> cmd = "ROUTE_TO_FOLDER/app < #{text}"
irb> stdin, stdout, stderr, wait_thr = Open3.popen3(cmd)
=> [#<IO:fd 10>, #<IO:fd 11>, #<IO:fd 13>, #<Thread:0x007f3a1a6f8820 run>]
当我这样做时:
irb> wait_thr.value
它也挂了,并且:
irb> wait_thr.status
=> "sleep"
所以......¿我该如何避免这些问题? ¿是不是认识到“app”失败了?
提前致谢
答案 0 :(得分:6)
wait_thr.pid
为您提供已启动流程的pid。只是做
Process.kill("KILL",wait_thr.pid)
当你需要杀死它时。
您可以将其与检测过程是否挂起(连续输出点)以两种方式之一进行组合。
1)设置等待进程的超时时间:
get '/process' do
text = "long text that will be used by app"
cmd = "ROUTE_TO_FOLDER/app < #{text}"
Open3.popen3(cmd) do |i,o,e,w|
begin
Timeout.timeout(10) do # timeout set to 10 sec, change if needed
# process output of the process. it will produce EOF when done.
until o.eof? do
# o.read_nonblock(N) ...
end
end
rescue Timeout::Error
# here you know that the process took longer than 10 seconds
Process.kill("KILL", w.pid)
# do whatever other error processing you need
end
end
end
2)检查过程输出。 (下面的代码是简化的 - 您可能不希望首先将进程的输出读入单个字符串buf然后进行处理,但我想你明白了。)
get '/process' do
text = "long text that will be used by app"
cmd = "ROUTE_TO_FOLDER/app < #{text}"
Open3.popen3(cmd) do |i,o,e,w|
# process output of the process. it will produce EOF when done.
# If you get 16 dots in a row - the process is in the continuous loop
# (you may want to deal with stderr instead - depending on where these dots are sent to)
buf = ""
error = false
until o.eof? do
buf << o.read_nonblock(16)
if buf.size>=16 && buf[-16..-1] == '.'*16
# ok, the process is hung
Process.kill("KILL", w.pid)
error = true
# you should also get o.eof? the next time you check (or after flushing the pipe buffer),
# so you will get out of the until o.eof? loop
end
end
if error
# do whatever error processing you need
else
# process buf, it contains all the output
end
end
end