【问题标题】:ruby script - redirect output from one script to another scriptruby 脚本 - 将输出从一个脚本重定向到另一个脚本
【发布时间】:2015-09-26 12:51:11
【问题描述】:

我很确定你们都知道 bash 管道。我要做的是读取一个 ruby​​ 脚本的输出并将其作为输入放入其他 ruby​​ 脚本

这是我迄今为止成功完成的:

生成输出的第一个文件

#one.rb

puts "hello"

以及处理输入的第二个文件

#two.rb

msg = gets.chomp
IO.write(File.dirname(__FILE__)+'\out.txt',msg)

现在,cygwin 命令(或 linux)(附带问题:这也可以在 windows cmd 或 powershell 中完成吗?)

ruby one.rb | ruby two.rb

瞧,out.txt 文件已创建,其中填充了字符串 hello。

但是,当我尝试在循环中执行此操作或处理某些数据流时,例如 10.times puts 'hello' 和循环读取它,它不起作用。有人可以帮我完成这个或告诉我我该怎么做吗?我只找到了一些 python 问题,但它是针对一些不同的和类似 bash 的方式。

谢谢!

【问题讨论】:

  • 也许你可以向我们展示一下不起作用的代码看起来像

标签: ruby bash pipeline data-stream


【解决方案1】:

您需要遍历标准输入行,而不是只读取一行 (msg = gets.chomp)

$stdin.each_line do |msg|
  # ...
end

这不会等待整个输出生成,它会在第一个进程打印行时处理流(忽略缓冲)。

以这两个脚本为例

# one.rb
i = 0
loop { puts i += 1 }

# two.rb
$stdin.each_line { |msg| puts "#{msg.chomp}!" }

第一个有无限输出,但你运行时仍然会看到输出

ruby one.rb | ruby two.rb

【讨论】:

  • 感谢您的回答,但您能确保我在流运行时处理流(在生成行时处理行)还是在生成后处理整个输出?
【解决方案2】:

您需要等到STDIN 在第二个脚本中发送EOF

试试:

#two.rb
msg = ""
while line = gets
  msg += line.chomp
end
IO.write(File.dirname(__FILE__)+'\out.txt',msg)

如果第一个脚本包含10.times { puts "hello" },你会得到:

hellohellohellohellohellohellohellohellohellohello

【讨论】:

  • 感谢您的回答,但您能确保我在流运行时处理流(在生成行时处理行)还是在生成后处理整个输出?
【解决方案3】:

要读取所有输入,在两个.rb中更改

msg = gets.chomp

msg = $stdin.read.chomp

如果要逐行阅读,请添加一些命令行标志:

ruby -n two.rb

而 two.rb 变成了

  BEGIN {out = File.open(File.dirname(__FILE__)+"/out.txt", "w")}
  out.write $_

在 Windows 上使用 / 代替 \ 是可以的。

【讨论】:

  • 将整个标准输入流读入内存不是一个好主意。
  • 很抱歉投了反对票,但是您的代码使用了很多在 Ruby 社区中被广泛反对的 Perlisms。
  • 嘿@max,我一直躲在角落里舔我的伤口 ;) 真诚的,你能指导我到某个地方,以便我了解 Ruby 社区标准吗?
  • 没有官方的 Ruby 风格指南,但this one 反映了社区采用的大部分做法。
猜你喜欢
  • 2020-01-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-11-07
相关资源
最近更新 更多