【发布时间】:2011-03-12 23:17:57
【问题描述】:
我有一个连续运行的应用程序,从服务器转储输出并将字符串发送到标准输出。我想用 Ruby 脚本处理这个输出。字符串是\n-终止的。
例如,我试图在命令行上运行它:
myapp.exe | my_script.rb
...my_script.rb 定义为:
while $stdin.gets
puts $_
end
我最终将使用正则表达式处理字符串并显示一些摘要数据,但现在我只是尝试连接基本功能。当我运行上面的,我得到以下错误:
my_script.rb:1:in `gets': Bad file descriptor (Errno::EBADF)
from my_script.rb:1
我在 Windows Server 2003 R2 SP2 和 Ruby 1.8.6 上运行它。
如何在 Ruby 脚本中连续处理标准输入? (继续不处理文件,而是运行直到我杀死它。)
编辑:
在某种程度上,我能够完成这项工作。有几个问题阻碍了我。一方面,可能是使用 Ruby 处理来自另一个进程 doesn't work on Windows 2003R2 的管道输入 stdin。下面 Adrian 建议的另一个方向是将我的脚本作为父进程运行,并使用 popen 连接到 myapp.exe 作为 forked 子进程。不幸的是,fork 没有在 Windows 中实现,所以这也不起作用。
最后我能够下载POpen4,这是一个在Windows 上实现popen 的RubyGem。结合 Adrian 的建议,我可以编写这个脚本来做我真正想要的——处理来自myapp.exe 的输出:
文件:my_script.rb
require 'rubygems'
require 'popen4'
status =
POpen4::popen4("myapp.exe") do |stdout, stderr, stdin, pid|
puts pid
while s = stdout.gets
puts s
end
end
此脚本回显来自myapp.exe 的输出,这正是我想要的。
【问题讨论】:
-
您是否尝试过在不使用管道的情况下运行 ruby 脚本并输入内容进行测试?你的代码可以在我的电脑上运行。
-
@Adrian:是的,我的脚本本身运行良好。正如预期和期望的那样,它与我输入的所有内容相呼应。
-
尝试简单的
gets,没有$stdin。如果这不起作用,您可能需要使用IO.popen使用另一个 ruby 脚本检查myapp.exe的输出中的不可打印字符。 -
@Adrian:不幸的是,
fork在 Windows 上不起作用,popen使用fork。我可以使用一些秘密咒语来让它发挥作用吗? -
我唯一能想到的就是暂时重写
myapp.exe在一定行数后退出,然后使用%x。