如何将 Ruby 脚本的输出传送到“head”不会出现管道损坏错误

发布于 2024-09-01 22:35:00 字数 465 浏览 3 评论 0原文

我有一个简单的 Ruby 脚本,如下所示

require 'csv'
while line = STDIN.gets
  array = CSV.parse_line(line)
  puts array[2]
end

但是当我尝试在像这样的 Unix 管道中使用此脚本时,我得到 10 行输出,然后是一个错误:

ruby lib/myscript.rb < data.csv  | head

12080450
12080451
12080517
12081046
12081048
12081050
12081051
12081052
12081054
lib/myscript.rb:4:in `write': Broken pipe - <STDOUT> (Errno::EPIPE)

是否有一种方法可以以阻止的方式编写 Ruby 脚本引发破损管道异常?

I have a simple Ruby script that looks like this

require 'csv'
while line = STDIN.gets
  array = CSV.parse_line(line)
  puts array[2]
end

But when I try using this script in a Unix pipeline like this, I get 10 lines of output, followed by an error:

ruby lib/myscript.rb < data.csv  | head

12080450
12080451
12080517
12081046
12081048
12081050
12081051
12081052
12081054
lib/myscript.rb:4:in `write': Broken pipe - <STDOUT> (Errno::EPIPE)

Is there a way to write the Ruby script in a way that prevents the broken pipe exception from being raised?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

暮年 2024-09-08 22:35:00

head 在读取所需的所有数据后关闭标准输出流。您应该处理异常并停止写入标准输出。一旦标准输出关闭,以下代码将中止循环:

while line = STDIN.gets
  array = CSV.parse_line(line)
  begin
    puts array[2]
  rescue Errno::EPIPE
    break
  end
end

head is closing the standard output stream after it has read all the data it needs. You should handle the exception and stop writing to standard output. The following code will abort the loop once standard output has been closed:

while line = STDIN.gets
  array = CSV.parse_line(line)
  begin
    puts array[2]
  rescue Errno::EPIPE
    break
  end
end
孤寂小茶 2024-09-08 22:35:00

我使用的技巧是将 head 替换为 sed -n 1,10p

这使管道保持打开状态,因此 ruby​​(或任何其他测试损坏管道并发出警告的程序)不会获取损坏的管道,因此不会发出警告。选择您想要的行数值。

显然,这并不是试图修改您的 Ruby 脚本。几乎可以肯定有一种方法可以在 Ruby 代码中做到这一点。然而,即使您无法选择修改生成消息的程序,“sed 而不是 head”技术也能发挥作用。

The trick I use is to replace head with sed -n 1,10p.

This keeps the pipe open so ruby (or any other program that tests for broken pipes and complains) doesn't get the broken pipe and therefore doesn't complain. Choose the value you want for the number of lines.

Clearly, this is not attempting to modify your Ruby script. There almost certainly is a way to do it in the Ruby code. However, the 'sed instead of head' technique works even where you don't have the option of modifying the program that generates the message.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文