Kvass
Kvass

Reputation: 8444

Ruby: Write to stdin and read from stdout?

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

Answers (2)

localhostdotdev
localhostdotdev

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

nurettin
nurettin

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

Related Questions