我有一个问题。
我想从另一个ruby脚本运行ruby脚本并捕获它的输出信息,同时让它输出到屏幕。
#!/usr/bin/env ruby
print "Enter your password: "
password = gets.chomp
puts "Here is your password: #{password}"
我运行的脚本文件:
output = `runner`
puts output.match(/Here is your (password: .*)/).captures[0].to_s
如你所见,有一个问题。
在start.rb的第一行,屏幕为空。
我在跑步者中看不到“输入您的密码:”。
有没有办法在跑步者脚本完成之前显示它的输出,并且仍然让我将它捕获到一个字符串,以便我可以处理信息,例如。像这个例子中那样使用匹配?
答案 0 :(得分:7)
STDOUT.print "Enter your password: "
password = gets.chomp
puts "Here is your password: #{password}"
注意 STDOUT.print
require "stringio"
buffer = StringIO.new
$stdout = buffer
require "runner"
$stdout = STDOUT
buffer.rewind
puts buffer.read.match(/Here is your (password: .*)/).captures[0].to_s
Enter your password: hello
password: hello
我最近在这里写了一篇文章:Output Buffering with Ruby
答案 1 :(得分:2)
试试这个:
rd, wr = IO::pipe
pid = Process.fork do
$stdout.reopen(wr)
rd.close
exec("command")
end
wr.close
rd.each do |line|
puts "line from command: #{line}"
end
Process.wait(pid)
如果您想捕获 stderr ,则类似。如果你需要捕获它们会更困难(Kernel.select
?)
编辑:一些解释。这是一个古老的Unix程序:pipe + fork +调用dup2(重新打开),具体取决于你想要的。简而言之:您创建一个管道作为孩子和父母之间的沟通方式。在fork之后,每个对等体关闭它不使用的管道端点,子对象重新(重新打开)您需要的通道到管道的写端点,最后父对象读取管道的读取通道。
答案 2 :(得分:1)
对于脚本无关的输出日志记录,您可能希望从终端模拟器(shell容器)启用它。 屏幕-L 要么 xterm -l 这将捕获模拟器中运行的任何shell或程序产生的所有输出,包括ruby脚本生成的输出。
答案 3 :(得分:0)
您可以使用tee将内容写入文件或管道,然后读取文件。
答案 4 :(得分:0)
看看POpen4。
它声称与平台无关(但我不认为它适用于jruby,你可以使用IO#popen
)。
答案 5 :(得分:0)
让您的脚本将其提示输出到stderr。
echo "Enter something" >&2
read answer
echo "output that will be captured"
如果您使用read -p
发出提示,则会为您完成此操作:
read -p "Enter something" answer
echo "output that will be captured"
答案 6 :(得分:0)
io = IO.popen(<your command here>)
log = io.readlines
io.close
现在在日志变量中,您拥有已执行命令的输出。解析它,转换它,或做任何你想做的事。