您无法使用反引号%x
或作为普通子 shell 执行您想要的操作,因为它们无法查看子命令输出的输出。
您可以使用 Open3popen2
或popen3
方法来完成。它们让您发送到被调用程序的 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