Reputation: 8444
I am writing a ruby program that is supposed to execute another program, pass values to it via stdin, read the response from its stdout, and then print the response. This is what I have so far.
#!/usr/bin/env ruby
require 'open3'
stdin, stdout, stderr = Open3.popen3('./MyProgram')
stdin.puts "hello world!"
output = stdout.read
errors = stderr.read
stdin.close
stdout.close
stderr.close
puts "Output:"
puts "-------"
puts output
puts "\nErrors:"
puts "-------"
puts errors
I am definitely doing something wrong here - when I run this it seems to be waiting for me to enter text. I don't want to be prompted for anything - I want to start ./MyProgram
, pass in "hello world!"
, get back the response, and print the response on the screen. How do I do this?
EDIT
Just in case it matters, MyProgram
is basically a program that keeps running until EOF, reading in and printing out stuff.
Upvotes: 9
Views: 6769
Reputation: 1895
a brief working way:
require 'open3'
out, err, status = Open3.capture3("./parser", stdin_data: "hello world")
out # string with standard output
err # string with error output
status.success? # true/false
status.exitstatus # 0 / 1 / ...
for more examples including sending binary input: https://ruby-doc.org/stdlib-2.6.3/libdoc/open3/rdoc/Open3.html#method-c-capture3
Upvotes: 0
Reputation: 11756
Try closing stdin before reading the output. Here's an example:
require 'open3'
Open3.popen3("./MyProgram") do |i, o, e, t|
i.write "Hello World!"
i.close
puts o.read
end
Here's a more succint way of writing it using Open3::capture3
: (beware, untested!)
o, e, s= Open3.capture3("./MyProgram", stdin_data: "Hello World!")
puts o
Upvotes: 14