3

I am trying to run gnuplot from ruby (not using an external gem) and parsing its textual output also. I tried IO.popen, PTY.spawn and Open3.popen3 but whenever I try to get the output it just "hangs" -I guess waiting for more output to come. I feel like its somehow done using Thread.new but I couldn't find the correct way to implement it.

Anyone know how it is done?

5
  • If that's standard output, try getting it via a shell command. Either enclose your command in backticks (`command`) or use %x(command) Commented Oct 31, 2014 at 19:28
  • I am trying to run an interactive program. Commented Oct 31, 2014 at 19:30
  • Somehow I missed the heading. Sorry. What exactly have you tried with Open3? Commented Oct 31, 2014 at 19:38
  • 1
    i, o, e, th = Open3.popen3('gnuplot'); putc o.readchar while !o.eof? Commented Oct 31, 2014 at 20:32
  • See "Extracting value from stdout of Open3.popen3 through RegEx and store it", which is most likely the answer to this question. Commented Oct 31, 2014 at 21:20

2 Answers 2

3

I guess this is what you want:

require 'pty'
require 'expect'

PTY.spawn('gnuplot') do |input, output, pid|
  str = input.expect(/gnuplot>/)
  puts str
  output.puts "mlqksdf"

  str = input.expect(/gnuplot>/)
  puts str
  output.puts "exit"
end
Sign up to request clarification or add additional context in comments.

Comments

1

The problem is that the sub-program is waiting for input that isn't being sent.

Typically, when we call a program that expects input on STDIN, we have to close STDIN, which then signals that program to begin processing. Look through the various Open3 methods and you'll see where stdin.close occurs in many examples, but they don't explain why.

Open3 also includes capture2 and capture3, which make it nice when trying to deal with a program that wants STDIN and you don't have anything to send to it. In both methods, STDIN is immediately closed, and the method returns the STDOUT, STDERR and exit status of the called program.


You need "expect" functionality. Ruby's Pty class includes an expect method.

Creates and managed pseudo terminals (PTYs). See also en.wikipedia.org/wiki/Pseudo_terminal

It's not very well documented though, and doesn't offer a lot of functionality from what I've seen. An example of its use is available at "Using Ruby Expect Library to Reboot Ruckus Wireless Access Points via ssh".

Instead, you might want to look at RubyExpect which is better documented and appears to be current.

5 Comments

I don't want to match a pattern from the output, I want to get it completely without blocking input.
sorry. Here's a better solution
OK, when I send a command through the stdin and close it I can read the stdout and stderr. But how will I reopen the stdin to send another command?
You don't. That's why you need "expect" which watches the interactive responses and then sends the next input.
OK, apparently I was wrong. At least, I can expect for "gnuplot>" lines, as Thomas suggested. Thank you!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.