I'm trying to write a Ruby script that interacts with a Node.js REPL. When I do:
i = IO.popen('node', 'r+')
i.write("console.log('hi')")
The write call returns the size of the write. But how do I get back the output of the REPL for processing? I've tried #read, and it does not return the output.
When you pipe things to node
, it expects to read a whole script from stdin. To make the above code work, you need to close the input before you can read the output.
i = IO.popen('node', 'r+')
i.write("console.log('hi')")
i.close_write
print i.read # => hi
Obviously, you need to write all the commands before you can read any output. If you want to interact with the REPL properly, you need to create a PTY. Here's a small example that runs a few commands and prints their outputs.
require 'pty'
require 'expect'
commands = ["console.log('hi')", "var a = 1", "console.log(a)"]
PTY.spawn("node") do |r,w,pid|
# r is node's stdout/stderr and w is stdin
r.expect('>')
commands.each do |cmd|
puts "Command: " + cmd
w.puts cmd
r.expect(/(.*?)\r\n(.*)>/m) {|res| print "Output: " + res[2] }
end
end
This kind of interaction with a REPL tends to be fragile, though. I don't know what you're trying to do but you might be better server by writing a small JavaScript program that evals your commands and returns the results in some easily-parsed format.