У меня есть простой сценарий 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 способом, который препятствует тому, чтобы поврежденное исключение канала было повышено?
head
закрывает стандартный поток вывода после того, как прочитал все необходимые данные. Вы должны обработать исключение и прекратить запись в стандартный вывод. Следующий код прервет цикл после закрытия стандартного вывода:
while line = STDIN.gets
array = CSV.parse_line(line)
begin
puts array[2]
rescue Errno::EPIPE
break
end
end
Я использую трюк, чтобы заменить head
на sed -n 1,10p
.
Это держит канал открытым, поэтому ruby
(или любая другая программа, которая проверяет наличие сломанных каналов и выдает жалобы) не получает сломанный канал и, следовательно, не жалуется. Выберите желаемое значение количества строк.
Ясно, что это не попытка изменить ваш сценарий Ruby. Почти наверняка есть способ сделать это в коде Ruby. Однако метод «sed вместо головы» работает даже там, где у вас нет возможности изменить программу, генерирующую сообщение.