Как вы перенаправляете вывод из скрипта Ruby в 'head', не получая ошибку сломанного канала - PullRequest
17 голосов
/ 17 мая 2010

У меня есть простой скрипт на 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 таким образом, чтобы предотвратить возникновение исключения из разорванного канала?

Ответы [ 2 ]

22 голосов
/ 17 мая 2010

head закрывает стандартный поток вывода после того, как прочитает все необходимые данные. Вы должны обработать исключение и прекратить запись в стандартный вывод. Следующий код прервет цикл после закрытия стандартного вывода:

while line = STDIN.gets
  array = CSV.parse_line(line)
  begin
    puts array[2]
  rescue Errno::EPIPE
    break
  end
end
10 голосов
/ 17 мая 2010

Уловка, которую я использую, состоит в том, чтобы заменить head на sed -n 1,10p.

. При этом канал остается открытым, поэтому ruby (или любая другая программа, которая проверяет наличие сломанных труб и жалуется), не получаетсломанная труба и поэтому не жалуется.Выберите желаемое значение для количества строк.

Очевидно, что это не попытка изменить ваш скрипт на Ruby.Существует почти наверняка способ сделать это в коде Ruby.Тем не менее, метод «sed вместо head» работает, даже если у вас нет возможности изменить программу, которая генерирует сообщение.

...