# Background process readling lines and responding

**URL:** <https://www.ruby-forum.com/t/background-process-readling-lines-and-responding/119708>\
**Category:** Ruby\
**Created:** [November 9, 2007, 12:45pm UTC](https://www.ruby-forum.com/t/background-process-readling-lines-and-responding/119708 "2007-11-09T12:45:10Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![braver](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/a88e57/32.png) [@braver](https://www.ruby-forum.com/u/braver)\
**Post date:** [November 9, 2007, 12:45pm UTC](https://www.ruby-forum.com/t/background-process-readling-lines-and-responding/119708/1 "2007-11-09T12:45:10Z")

</div>

Greetings – I’m debugging a way to call a command-line executable as a  
server. In normal life it behaves like grep, reading lines from stdin  
and printing responses to stdout. So I’m debugging the Ruby wrapper on  
grep, as the original takes a long time to load (thus the whole  
exercise). Here’s what I got – but it swallows the first line of input  
and doesn’t respond! Why?

#!/usr/bin/env ruby

require ‘optparse’  
require ‘ostruct’

class Server

def initialize(cmd\_line)  
puts “starting server with the following command line:”  
puts cmd\_line  
@pipe = IO.popen cmd\_line, “r+”  
end

def process(sent)  
return nil if sent.nil? or sent =~ /^\s+$/

```
puts "sending: [#{sent}]"
@pipe.write(sent)

@pipe.readlines

```

end  
end # class

def main  
o = OpenStruct.new  
files = OptionParser.new do |opt|  
opt.on("-e", “–exe EXE”, “server executable basename”) { |val|  
o.exe = val }  
end.parse(\*ARGV)

ps = Server.new(o.exe)

STDIN.each\_line do |line|  
out = ps.process(line)  
puts out  
end  
end

main if $0 == **FILE**

– Here’s what happens when I try to use it:

$ aha-grep-server.rb -e “grep abra”  
starting server with the following command line:  
grep abra  
abracadabra  
sending: [abracadabra  
]

– then it just hangs there, @pipe.readlines returning nothing. What’s  
the right IO semantics here?

Cheers,  
Alexy

---

<div class="post-metadata">

**Author:** ![braver](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/a88e57/32.png) [@braver](https://www.ruby-forum.com/u/braver)\
**Post date:** [November 9, 2007, 5:17pm UTC](https://www.ruby-forum.com/t/background-process-readling-lines-and-responding/119708/2 "2007-11-09T17:17:41Z")

</div>

Alexy,

The first thing that comes to mind is that you are writing the sent  
text to the pipe and then immediately calling readlines; is that  
enough time for grep to process its work and write the result back to  
the pipe?

Also, by “but it swallows the first line of input and doesn’t  
respond!”, do you mean that you are not able to write anymore text  
(indicating that readlines might be blocking) or just that it never  
shows grep’s result?

-Szymon

---

<div class="post-metadata">

**Author:** ![braver](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/a88e57/32.png) [@braver](https://www.ruby-forum.com/u/braver)\
**Post date:** [November 9, 2007, 11:34pm UTC](https://www.ruby-forum.com/t/background-process-readling-lines-and-responding/119708/3 "2007-11-09T23:34:33Z")

</div>

Hey Szymon – good to see you here! If, instead of “grep something”, I  
give it a Ruby program which reads and writes lines, it works OK. I  
wonder what’s different between these:

– a.rb:  
IO.popen(“ruby b.rb”, “r+”) do |f|  
STDIN.each\_line do |x|  
@write = f.puts x.to\_s  
@read = f.gets  
puts “back: #{@read}”  
end  
end

– b.rb:  
STDOUT.sync = true

def readWrite  
while @string = gets  
@string.chomp!  
puts “received =\> #{@string}”  
end  
end

readWrite

$ ruby a.rb  
/z/aha/ru/popen ruby a.rb  
abra  
back: received =\> abra  
cadabra  
back: received =\> cadabra  
…  
– can enter strings, they’re echoed back.

Now, let’s call “grep abra” instead of b.rb:  
– call-grep.rb:  
IO.popen(“grep abra”, “r+”) do |f|  
STDIN.each\_line do |x|  
puts “sending: #{x}”  
@write = f.puts x.to\_s  
@read = f.gets  
puts “back: #{@read}”  
end  
end

$ ruby call-grep.rb:  
/z/aha/ru/popen ruby call-grep.rb  
abra  
sending: abra  
cadabra  
– already unresponsive.

---

<div class="post-metadata">

**Author:** ![braver](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/a88e57/32.png) [@braver](https://www.ruby-forum.com/u/braver)\
**Post date:** [November 11, 2007, 9:09am UTC](https://www.ruby-forum.com/t/background-process-readling-lines-and-responding/119708/4 "2007-11-11T09:09:59Z")

</div>

I guess you should make sure to flush the pipe caches before trying to  
get output from the background process. If the data you sent in the  
first place is still sitting there, you won’t get anything back…

Anyway, I had better luck with using two separate threads for writing  
and reading to/from the pipe. This one below just hangs because the  
buffers fill up and it can’t send more data before reading from the  
output. Note that this is on Cygwin on WinXP SP2 - the amount of data  
which triggers the deadlock may wary on other systems.

open(’|tr [a-z] [A-Z]’, ‘w+’) do |tr|  
30000.times{tr.puts ‘hehe’}  
tr.close\_write  
puts tr.read  
end

But this one echoes back the HEHE’s just as expected:

open(’|tr [a-z] [A-Z]’, ‘w+’) do |tr|  
Thread.new do  
30000.times{tr.puts ‘hehe’}  
tr.close\_write  
end  
puts tr.read  
end
