从Ruby调用Perl脚本

Calling a Perl script from Ruby

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

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

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

1
upgradestatus =  `#{upgradearray[arraylocation]}`

这将是我的代码的相关部分。我尝试过其他一些不同的方法,但是每次我都会遇到相同的情况。当脚本开始运行时,它需要输入,所以它就位于那里。


您不能使用backticks、%x或作为普通的子shell执行您想要的操作,因为它们缺乏监视子命令输出的能力。

您可以使用Open3的popen2popen3方法来实现。它们允许您为被调用的程序发送到stdin流,并从stdout接收数据。popen3还允许您查看/捕获stdout流。不幸的是,通常您必须发送,然后在被调用程序返回其信息之前关闭stdin流,这可能是Perl脚本的情况。

如果您需要更多的控制,可以考虑使用Ruby的内置Pty模块。它的设计目的是让您通过脚本机制与正在运行的应用程序进行对话。您必须设置代码来查找提示,然后通过发送适当的数据来响应它们。它可能很简单,也可能是一个主要的PITA,这取决于您所说的代码。

这是open命令的示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
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
"
w.puts"
144"
p m.gets #=>"
144: 2 2 2 2 3 3
"
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