Подтвердить что ты не робот

Как вы делаете вывод на выходе из Ruby script в 'head', не получая прерывистую трубную ошибку

У меня есть простой Ruby script, который выглядит как

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

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

4b9b3361

Ответ 1

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

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

Ответ 2

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

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

Ясно, что это не попытка изменить ваш Ruby script. Почти наверняка есть способ сделать это в коде Ruby. Однако технология "sed вместо головы" работает даже там, где у вас нет возможности модифицировать программу, которая генерирует сообщение.