Setting input for system() calls in ruby

2019-06-25 13:13发布

问题:

I'm trying to download a file using net/sftp and pass its contents as the stdin for a command-line app. I can do it by first writing the file to disk but I'd rather avoid that step.

Is there any way to control the input to a program invoked with system() in ruby?

回答1:

Don't use system at all for this sort of thing, system is best for running an external command that you don't need to talk to.

Use Open3.open3 or Open3.open2 to open up some pipes to your external process then write to the stdin pipe just like writing to any other IO channel; if there is any output to deal with, then you can read it straight from the stdout pipe just like reading from any other input IO channel.



回答2:

Something like this perhaps (using open as mu suggested)?

contents = "Hello, World!"
open('|echo', 'w') { puts contents }


回答3:

This can also be accomplished with IO.expect

require 'pty'
require 'expect'

str = "RUBY_VERSION"

PTY.spawn("irb") do |reader, writer|
  reader.expect(/0> /)
  writer.puts(str)
  reader.expect(/=> /)
  answer = reader.gets
  puts "Ruby version from irb: #{answer}"
end

This waits for the spawned process to display "0> " (the end of an irb prompt) and when it sees that prints a defined string. It then looks for the irb to return by waiting for it to display "=> " and grabs the data returned.



标签: ruby system