Maybe this one has already been answered somewhere. If so, my
searching skills really suck.
How can I start a sub-process from Ruby and read its standard error
and standard output stream separately? I have tried to do it with
IO.popen, but it only reads the output stream. The Process module
doesn’t help either.
Cheers,
Thiago A.
Hi !
I don’t know if this is the best way to do it, but here is how I’ll do :
rd,wt = IO.pipe # Prepare the pipe to get the output
id = fork do
Here we are in the child process
First get the system id of the pipe
$stderr.reopen(f)
Then launch your process here
exec(“prog”, arg1, …)
end
Here you can read the error output from rd
If you want to wait for the end of the other process first :
Process.waitpid(id)
Pierre
PS: I hope this works as I am not on a UNIX machine and fork does not
work However I tried the IO.reopen part and this works fine.
Thiago A. a écrit :
Thiago A. wrote:
Thiago A.
require ‘open3’
stdin, stdout, stderr = Open3.popen3(
‘ruby -e “$stdout.sync = true; while (s=gets); 5.times
{$stderr.puts(s.reverse); puts s}; end”’)
t1 = Thread.new do
while (s=stderr.gets)
puts “STDERR: #{s.inspect}”
end
puts “STDERR: DONE”
end
t2 = Thread.new do
while (s=stdout.gets)
puts “STDOUT: #{s.inspect}”
end
puts “STDOUT: DONE”
end
stdin.puts “foo”
stdin.close
[t1, t2].each do |t| t.join end
The purpose of the $stdout.sync = true in the subprocess is so that you
can read the subprocess’s stdout as soon as it is written to. If all you
care about is getting all the stdout eventually, you don’t need it.