2016-10-19 3 views
2

Я ищу, чтобы программа ruby ​​(задача рейка) наблюдала выход из другой задачи рейка. Выходная запись выводится на stderr. Я бы хотел прочитать эти строки. У меня проблемы с настройкой. Если у меня есть писатель (stdout_writer.rb), который постоянно печатает что-то:ruby ​​pipes, IO и stderr redirect

#!/usr/bin/env ruby 
puts 'writing...' 
while true 
    $stdout.puts '~' 
    sleep 1 
end 

и файл, который читает его и эхо-сигналы (stdin_reader.rb):

#!/usr/bin/env ruby 
puts 'reading...' 
while input = ARGF.gets 
    puts input 
    input.each_line do |line| 
    begin 
     $stdout.puts "got line #{line}" 
    rescue Errno::EPIPE 
     exit(74) 
    end 
    end 
end 

, и я стараюсь, чтобы иметь они работают вместе, ничего не происходит:

$ ./stdout_writer.rb 2>&1 | ./stdin_reader.rb 
$ ./stdout_writer.rb | ./stdin_reader.rb 

ничего ... хотя, если я просто эхо в stdin_reader.rb, я получаю то, что я ожидал:

[email protected]:~/projects/opera_events/sendgrid-example-operaevent$ echo "ok true" | ./stdin_reader.rb 
reading... 
ok true 
got line ok true 
[email protected]:~/projects/opera_events/sendgrid-example-operaevent$ 

так как я могу настроить сценарий, который получает stderr в него, чтобы он мог читать его по очереди? Дополнительная информация: это будет убунту служба script1.rb | script2.rb выскочка, где script1 посылает сообщение, и Скрипт2 проверяет, что сообщение было отправлено script1

ответ

0

Проблема, кажется, что, как stdout_writer работает бесконечно, stdin_reader никогда не получит шанс прочитать STDOUT от stdout_writer как труба, в этом случае ждет stdout_writer, который должен быть закончен, прежде чем stdin_reader начнет чтение. Я проверил это, изменив while true на 5.times do. Если вы сделаете это, и подождите 5 секунд, результат ./stdout_writer.rb | ./stdin_reader.rb является

reading... 
writing... 
got line writing... 
~ 
got line ~ 
~ 
got line ~ 
~ 
got line ~ 
~ 
got line ~ 
~ 
got line ~ 

Это не проблема с самого кода, но в большей степени проблема с тем, как рубин исполнение с точки зрения STDOUT | STDIN погрузочно-разгрузочных работ ,

Кроме того, я не думаю, что когда-либо узнал, насколько я изучил этот вопрос. Спасибо за удовольствие.

1

Выход из stdout_writer.rb буферизуется Ruby, поэтому процесс чтения не видит его. Если вы подождете достаточно долго, вы увидите, что результат появится в кусках.

Вы можете включить буферизацию выключить и получить результат вы ожидаете от setting sync to true на $stdout в начале stdout_writer.rb:

$stdout.sync = true 
Смежные вопросы