我正在编写一段Ruby脚本,最终要启动一个耗时较长的系统进程。我需要从该进程的stderr读取内容并根据输出做出反应。
目前我的实现方式如下:
Open3.popen3(cmd_to_run) do |stdin, stdout, stderr, waitthread|
stderr.each_line do |line|
# look out for specific lines and react to them accordingly
end
end
但我也见过使用 kernel#select 实现类似功能的实现方式:
Open3.popen3(cmd_to_run) do |stdin, stdout, stderr, waitthread|
io = select([stderr], nil, nil, 30)
if io.nil?
log("Command timed out during Kernel#select")
return
end
io[0][0].each_line do |line|
# look out for specific lines and react to them accordingly
end
end
我已阅读《Ruby程序员修炼之道》中有关select的解释,但我不确定为什么要使用它(或者是否需要使用)。第一种方法看起来也能实现同样的功能。
stdout
时,如果没有任何内容(尚未),则您的监视进程将阻塞。想象一下,您的系统进程将一些诊断信息打印到stderr
并等待您的回复,但它是stderr
而不是stdout
,因此您将永远在stdout
上等待某些内容。select
从列表中返回第一个可用的IO对象,其中发生了某些事情,因此您可以处理它,并且read
不会阻塞,因为有东西。 - Victor Moroz