我正在使用命令行程序,它的工作原理如下:
$ ROUTE_TO_FOLDER/app < "long text"
Run Code Online (Sandbox Code Playgroud)
如果使用参数"app"需要写入"长文本",那么它将填充带有结果的文本文件.如果没有,它将连续用点填充文本文件(我无法处理或修改"app"的代码以避免这种情况).
在ruby脚本中有一行如下:
text = "long text that will be used by app"
output = system("ROUTE_TO_FOLDER/app < #{text}")
Run Code Online (Sandbox Code Playgroud)
现在,如果文本写得很好,就不会有问题,我会得到一个如前所述的输出文件.文本写得不好时会出现问题.接下来发生的是我的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>]
Run Code Online (Sandbox Code Playgroud)
当我做:
irb> wait_thr.value
Run Code Online (Sandbox Code Playgroud)
它也挂起,并且:
irb> wait_thr.status
=> "sleep"
Run Code Online (Sandbox Code Playgroud)
所以...¿我怎样才能避免这些问题?¿是不是认识到"app"失败了?
提前致谢
wait_thr.pid
为您提供已启动流程的pid.做就是了
Process.kill("KILL",wait_thr.pid)
Run Code Online (Sandbox Code Playgroud)
当你需要杀死它.
您可以将其与检测过程是否挂起(连续输出点)以两种方式之一进行组合.
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
Run Code Online (Sandbox Code Playgroud)
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
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
3379 次 |
最近记录: |