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 Arrais
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 Arrais a écrit :
···
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 Arrais
Thiago Arrais wrote:
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 Arrais
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.
···
--
vjoel : Joel VanderWerf : path berkeley edu : 510 665 3407