Почему IO :: WaitReadable вызывается для STDOUT иначе, чем для STDERR?

Учитывая, что Я хочу протестировать неблокирующее чтение из длинной команды, я создал следующий сценарий, сохранил его как long , сделал его исполняемым с помощью chmod 755 и поместил его в свой путь ( сохранено как ~ / bin / long , где ~ / bin находится на моем пути).

Я использую вариант * nix с ruby ​​1.9.2p290 (2011- 07-09, ревизия 32553) [x86_64-darwin11.0.0] скомпилирован со значениями по умолчанию RVM. Я не использую Windows,и поэтому я не уверен, подойдет ли вам тестовый сценарий, если вы это сделаете.

#!/usr/bin/env ruby

3.times do
  STDOUT.puts 'message on stdout'
  STDERR.puts 'message on stderr'
  sleep 1
end

Почему long_err создает каждое сообщение STDERR, поскольку оно печатается как «long»

def long_err( bash_cmd = 'long', maxlen = 4096)
  stdin, stdout, stderr = Open3.popen3(bash_cmd)
  begin
    begin
      puts 'err -> ' + stderr.read_nonblock(maxlen)
    end while true
  rescue IO::WaitReadable
    IO.select([stderr])
    retry
  rescue EOFError
    puts 'EOF'
  end
end

, а long_out ] остается заблокированным до тех пор, пока не будут напечатаны все сообщения STDOUT?

def long_out( bash_cmd = 'long', maxlen = 4096)
  stdin, stdout, stderr = Open3.popen3(bash_cmd)
  begin
    begin
      puts 'out -> ' + stdout.read_nonblock(maxlen)
    end while true
  rescue IO::WaitReadable
    IO.select([stdout])
    retry
  rescue EOFError
    puts 'EOF'
  end
end

Я предполагаю, что вы потребуете 'open3' перед тестированием любой функции.

Почему IO :: WaitReadable вызывается иначе для STDOUT, чем STDERR?

Обходные пути с использованием других способов запуска подпроцессов также приветствуются, если они у вас есть.

5
задан the Tin Man 2 December 2013 в 18:54
поделиться