# Having trouble reading from stderr

**URL:** <https://www.ruby-forum.com/t/having-trouble-reading-from-stderr/130172>\
**Category:** Ruby\
**Created:** [February 26, 2008, 1:50am UTC](https://www.ruby-forum.com/t/having-trouble-reading-from-stderr/130172 "2008-02-26T01:50:24Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![crose1](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/9fc348/32.png) [@crose1](https://www.ruby-forum.com/u/crose1)\
**Post date:** [February 26, 2008, 1:50am UTC](https://www.ruby-forum.com/t/having-trouble-reading-from-stderr/130172/1 "2008-02-26T01:50:24Z")

</div>

Hi,

I’m trying to write a script that will establish an ssh tunnel through  
“[gatewaymachine.com](http://gatewaymachine.com)” to a “targetmachine” on the other side. Sometimes  
there’s already a tunnel established on the same port, in which case,  
the command fails with an error message.

I’d like to be able to read the error message from the script. If the  
script failed due to an incorrect port number, I’d like increment the  
port number and try again.

Based on my google search, the popen3 command from the open3 library is  
what I want to use.

But when I try to read from stderr, the read command never returns.  
Here’s the code:

require ‘open3’

stdin, stdout, stderr = Open3.popen3(“ssh removed\_email\_address@domain.invalid -i  
/Users/crasch/.ssh/id\_rsa.pub -L 2222:targetmachine:22 -N”)

puts stderr.read \<—hangs indefinitely here

Any suggestions for what might be happening? Thanks for any suggestions  
you may wish to provide.

Chris

---

<div class="post-metadata">

**Author:** ![crose1](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/9fc348/32.png) [@crose1](https://www.ruby-forum.com/u/crose1)\
**Post date:** [February 26, 2008, 3:00am UTC](https://www.ruby-forum.com/t/having-trouble-reading-from-stderr/130172/2 "2008-02-26T03:00:42Z")

</div>

Hey,

Check out the Net::SSH module. It’ll probably do what you want.

[http://net-ssh.rubyforge.org/](http://net-ssh.rubyforge.org/)

Comes with Ruby, if I’m not mistaken.

Cheers,  
Arlen.

---

<div class="post-metadata">

**Author:** ![crose1](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/9fc348/32.png) [@crose1](https://www.ruby-forum.com/u/crose1)\
**Post date:** [February 26, 2008, 3:15am UTC](https://www.ruby-forum.com/t/having-trouble-reading-from-stderr/130172/3 "2008-02-26T03:15:56Z")

</div>

The fix is simple - replace ‘read’ with ‘gets’, ie, puts stderr.gets.

---

<div class="post-metadata">

**Author:** ![crose1](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/9fc348/32.png) [@crose1](https://www.ruby-forum.com/u/crose1)\
**Post date:** [February 26, 2008, 4:20am UTC](https://www.ruby-forum.com/t/having-trouble-reading-from-stderr/130172/4 "2008-02-26T04:20:25Z")

</div>

Thanks! However, stderr.gets hangs as well. Here’s what the irb  
session looks like:

irb(main):001:0\> require ‘open3’  
=\> true  
irb(main):002:0\> stdin, stdout, stderr = Open3.popen3(“ssh  
removed\_email\_address@domain.invalid -i /Users/crasch/.ssh/id\_rsa.pub -L  
2222:targetmachine:22 -N”)  
=\> [#IO:0x10c0534, #IO:0x10c04f8, #IO:0x10c0494]  
irb(main):003:0\> stderr.gets \<— hangs here

Could it be that stderr has received a partial error message, but won’t  
write anything out until it receives a signal  
that ssh process has ended?

Chris

---

<div class="post-metadata">

**Author:** ![crose1](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/9fc348/32.png) [@crose1](https://www.ruby-forum.com/u/crose1)\
**Post date:** [February 26, 2008, 8:25pm UTC](https://www.ruby-forum.com/t/having-trouble-reading-from-stderr/130172/5 "2008-02-26T20:25:48Z")

</div>

After I generated my own key file and ran your example (except with  
gets) and with my key file, the system waited for a few Minutes and  
generated this:

poplar% time ./x.rb  
ssh: connect to host [gatewaymachine.com](http://gatewaymachine.com) port 22: Operation timed out

./x.rb 0.00s user 0.01s system 0% cpu 2:14.79 total

If nothing is able to be read from stderr, I suppose the read/gets  
call will hang - you might want to put the read of stderr in a  
thread. Something like this:

Thread.new { loop { puts “Err stream: #{stderr.gets}” } }

you can always receive a partial msg by placing the number of bytes to  
read in the read call, ie stderr.read(5) …
