从Ruby调用Perl脚本

时间:2013-01-07 19:11:04

标签: ruby perl bash

我目前正在尝试找出一种从Ruby调用Perl脚本的方法,并将其输出,就好像我在终端中一样,如果需要,我可以提供输入。

我已经弄清楚如何做到这一点并在事后得到输入,但因为Perl脚本仍在运行,我无法运行其他任何东西。

我应该注意,我无法编辑Perl脚本。正在提供这些脚本,并且正在制作这个Ruby脚本,以便更轻松地运行所有Perl脚本并确保它们的顺序正确。

upgradestatus =  `#{upgradearray[arraylocation]}`

这将是我的代码的相关部分。我已经尝试了一些其他如何做到这一点的变化,但我每次都得到相同的情况。当脚本开始运行时,它需要输入,所以它就在那里。

1 个答案:

答案 0 :(得分:0)

你无法使用反引号,%x或普通的子shell做你想做的事,因为它们无法观察子命令输出的输出。

您可以使用Open3的popen2popen3方法执行此操作。它们允许您将STDIN流发送到被调用程序,并从STDOUT接收数据。 popen3也允许您查看/捕获STDOUT流。不幸的是,通常你必须发送,然后在被调用程序返回其信息之前关闭STDIN流,这可能是Perl脚本的情况。

如果您需要更多控制,请查看使用Ruby的内置Pty模块。它旨在让您通过脚本机制与正在运行的应用程序通信。您必须设置代码以查找提示,然后通过发回适当的数据来响应它们。它可以很简单,也可以是主要的PITA,具体取决于您正在与之交谈的代码。

这是open命令的示例:

PTY.open {|m, s|
p m      #=> #<IO:masterpty:/dev/pts/1>
p s      #=> #<File:/dev/pts/1>
p s.path #=> "/dev/pts/1"
}

# Change the buffering type in factor command,
# assuming that factor uses stdio for stdout buffering.
# If IO.pipe is used instead of PTY.open,
# this code deadlocks because factor's stdout is fully buffered.
require 'io/console' # for IO#raw!
m, s = PTY.open
s.raw! # disable newline conversion.
r, w = IO.pipe
pid = spawn("factor", :in=>r, :out=>s)
r.close
s.close
w.puts "42"
p m.gets #=> "42: 2 3 7\n"
w.puts "144"
p m.gets #=> "144: 2 2 2 2 3 3\n"
w.close
# The result of read operation when pty slave is closed is platform
# dependent.
ret = begin
        m.gets          # FreeBSD returns nil.
    rescue Errno::EIO # GNU/Linux raises EIO.
        nil
    end
p ret #=> nil
相关问题