从Ruby运行shell命令:在显示输出时捕获输出?
我有个问题。
我想从另一个ruby脚本运行ruby脚本并捕获它的输出信息,同时让它输出到屏幕。
跑步者
#!/usr/bin/env ruby print "Enter your password: " password = gets.chomp puts "Here is your password: #{password}"
我运行的脚本文件:
start.rb
output = `runner` puts output.match(/Here is your (password: .*)/).captures[0].to_s
如你所见,这是一个问题。
在start.rb的第一行,屏幕为空。
我在跑步者中看不到“输入你的密码:”。
有没有办法在它完成之前显示转轮脚本的输出,并且仍然让我将它捕获到一个字符串,以便我可以处理信息,例如。 在这个例子中使用匹配?
runner.rb
STDOUT.print "Enter your password: " password = gets.chomp puts "Here is your password: #{password}"
注意 STDOUT.print
start.rb
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
阅读更多…
我最近在这里写了一篇文章: 使用Ruby输出缓冲
试试这个:
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之后,每个对等体关闭它不使用的管道端点,子对象重新(重新打开)您需要的通道到管道的写端点,最后父对象读取管道的读取通道。
对于脚本无关的输出日志记录,您可能希望从终端仿真器(shell容器)启用它。 screen -L OR xterm -l这将捕获在模拟器中运行的任何shell或程序产生的所有输出,包括ruby脚本生成的输出。
您可以使用tee将内容写入文件或管道,然后读取文件。
看看POpen4 。 它声称是独立于平台的(但我不认为它适用于jruby,你可以使用IO#popen
)。
让您的脚本将其提示输出到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"
io = IO.popen() log = io.readlines io.close
现在在log变量中你有执行命令的输出。 解析它,转换它,或做任何你想做的事情。
- -bash:/ usr / local / bin / heroku:/ usr / local / bin / ruby:bad interpreter:没有这样的文件或目录
- 打开终端时正确的Ruby版本
- .gsub(/ \ … /,“”)。worub(/ \(/,“”)。gsub(/ \)/,“”)。gsub(/ \ localhost /,“”)<=这是少数
- Monit捆绑exec rails s
- 使用特定版本的ruby在cron上运行gem
- 是否可以编写连接到Heroku并运行Ruby命令的shell命令?
- 如何为所需的Ruby版本设置正确的shebang
- Ruby selenium webdriver无法找到Mozilla geckodriver
- 为什么我需要在我的路径中添加〜/ .rbenv / bin?