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