【问题标题】:Piping stdin to ruby script via `myapp | myscript.rb`通过 `myapp | 管道标准输入到 ruby​​ 脚本我的脚本.rb`
【发布时间】: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

标签: ruby stdin


【解决方案1】:

尝试简单的gets,不使用$stdin。如果这不起作用,您可能需要使用 IO.popen 使用另一个 ruby​​ 脚本检查 myapp.exe 的输出中的不可打印字符。

【讨论】:

    【解决方案2】:

    gets 并不总是使用标准输入,而是尝试打开文件。

    SO

    【讨论】:

    • 当我在我的代码中用ARGF 替换$stdin 时,我仍然得到同样的错误。我做得对吗?
    【解决方案3】:

    尝试通过显式调用 ruby​​ 来执行您的 Ruby 脚本:

    myapp.exe | ruby my_script.rb
    

    在依赖 Windows 根据文件关联调用正确程序时,我在 Ruby 中使用标准输入时遇到了一些奇怪的行为。

    【讨论】:

      猜你喜欢
      • 2011-04-29
      • 2015-01-18
      • 1970-01-01
      • 1970-01-01
      • 2012-04-15
      • 2012-02-29
      • 1970-01-01
      • 2013-10-24
      相关资源
      最近更新 更多