# Reading from standard error

**URL:** <https://www.ruby-forum.com/t/reading-from-standard-error/55621>\
**Category:** Ruby\
**Created:** [March 22, 2006, 3:34pm UTC](https://www.ruby-forum.com/t/reading-from-standard-error/55621 "2006-03-22T15:34:29Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![thiagoalessio](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/d6d6ee/32.png) [@thiagoalessio](https://www.ruby-forum.com/u/thiagoalessio)\
**Post date:** [March 22, 2006, 3:34pm UTC](https://www.ruby-forum.com/t/reading-from-standard-error/55621/1 "2006-03-22T15:34:29Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![thiagoalessio](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/d6d6ee/32.png) [@thiagoalessio](https://www.ruby-forum.com/u/thiagoalessio)\
**Post date:** [March 22, 2006, 5:10pm UTC](https://www.ruby-forum.com/t/reading-from-standard-error/55621/2 "2006-03-22T17:10:37Z")

</div>

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 :

---

<div class="post-metadata">

**Author:** ![thiagoalessio](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/d6d6ee/32.png) [@thiagoalessio](https://www.ruby-forum.com/u/thiagoalessio)\
**Post date:** [March 22, 2006, 6:55pm UTC](https://www.ruby-forum.com/t/reading-from-standard-error/55621/3 "2006-03-22T18:55:18Z")

</div>

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.
