Popen3

Has anyone had good luck using popen3 to control an interactive program? I
get the initial output from the program but am not having any luck writing
to the applications stdin. If anyone has a non-trivial example of how to
make this work, I would appreciate it.

Has anyone had good luck using popen3 to control an interactive program?
I get the initial output from the program but am not having any luck
writing to the applications stdin. If anyone has a non-trivial example
of how to make this work, I would appreciate it.

I can’t promise anything, but you could try using ‘expect.rb’ in the
standard library. Pickaxe or Nutshell might have something on it, but the
source is small, and it is obviously designed to drive interactive
programs.

Gavin

I have not had any problems with this.
Can you show some relevant code and where you are having
problems?

···

On Monday, 29 September 2003 at 11:13:55 +0900, Alex Nelson wrote:

Has anyone had good luck using popen3 to control an interactive program? I
get the initial output from the program but am not having any luck writing
to the applications stdin. If anyone has a non-trivial example of how to
make this work, I would appreciate it.


Jim Freeze

Mencken and Nathan’s Fifteenth Law of The Average American:
The worst actress in the company is always the manager’s wife.

Here is my class as it currently stands:

#!/usr/bin/ruby

require "open3"
require “timeout”

class Controller

def initialize(p_program, p_read_timeout = 1.0, p_write_timeout = 1.0)
puts “Entering Controller::initialize” if $DEBUG
@outMsg = Array.new
@errMsg = Array.new
@program = p_program
@read_timeout = p_read_timeout
@write_timeout = p_write_timeout
puts “Leaving Controller::intialize” if $DEBUG
end

def start
	puts "Entering Controller::start" if $DEBUG
  @p_in, @p_out, @p_err = Open3.popen3(@program)
	puts "Leaving Controller::start" if $DEBUG
end

def getStdOut
puts “Entering Controller::getStdOut” if $DEBUG
timeout @read_timeout do
reads = IO::select([@p_out], nil, nil, @read_timeout)
if reads
unless reads.empty?
puts “Returning gets from stdout for Controller::getStdOut” if $DEBUG
return @p_out.gets
else
puts “Returning nil for Controller::getStdOut” if $DEBUG
return nil
end
else
puts “Returning nil for Controller::getStdOut” if $DEBUG
return nil
end
end
end

def getStdErr
puts “Entering Controller::getStdErr” if $DEBUG
timeout @read_timeout do
reads = IO::select(nil, nil, [@p_err], @read_timeout)
if reads
unless reads.empty?
puts “Returning gets from stderr for Controller::getStdErr” if $DEBUG
return @p_err.gets
end
else
puts “Returning nil for Controller::getStdErr” if $DEBUG
return nil
end
end
end

def putMsg(msg)
puts “Entering Controller::putMsg” if $DEBUG
timeout @write_timeout do
puts "Sending <#{msg}> to #{@program}"
writes = IO::select(nil, [@p_in], nil, @write_timeout)
if writes
@p_in.print(msg)
else
puts “File object was not ready during select for Controller::putMsg” if $DEBUG
end
end
puts “Leaving Controller::putMsg” if $DEBUG
end

def waitFor(waitMsg, timeOut = 10)
puts “Entering Controller::waitFor” if $DEBUG
done = 0
msgList = []
timeout timeOut do
while ((msg = getStdOut) && (done == 0))
if msg
puts "Msg from nwnserver: <#{msg}>"
if (msg =~ /#{waitMsg}/)
done = 1
end
msgList << msg
else
puts "No message yet"
end
end
end
puts “Returning message list for Controller::waitFor” if $DEBUG
return(msgList)
end

end