1

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

我已经想出了如何做到这一点并在事后获得输入,但由于 Perl 脚本仍在运行,我无法运行其他任何东西。

我应该注意我不能编辑 Perl 脚本。提供了这些脚本,并且制作了这个 Ruby 脚本,以使运行所有 Perl 脚本的过程更容易,并确保它们的顺序正确。

upgradestatus =  `#{upgradearray[arraylocation]}`

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

4

1 回答 1

0

您无法使用反引号%x或作为普通子 shell 执行您想要的操作,因为它们无法查看子命令输出的输出。

您可以使用 Open3popen2popen3方法来完成。它们让您发送到被调用程序的 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
于 2013-01-07T21:34:08.730 回答