Как Вы передаете вывод по каналу из сценария Ruby для 'направлений', не получая поврежденную ошибку канала

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

17
задан dan 16 May 2010 в 21:14
поделиться

2 ответа

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

while line = STDIN.gets
  array = CSV.parse_line(line)
  begin
    puts array[2]
  rescue Errno::EPIPE
    break
  end
end
22
ответ дан 30 November 2019 в 12:19
поделиться

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

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

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

10
ответ дан 30 November 2019 в 12:19
поделиться
Другие вопросы по тегам:

Похожие вопросы: