Redirecting stdout / stderr from spawn () to a string in Ruby

I would like to execute an external process in Ruby using spawn (for several parallel child processes) and assemble stdout or stderr into a string, similar to what can be done with the Python subprocess Popen.communicate ().

I tried redirecting: out /: err to a new StringIO object, but this throws an ArgumentError, and temporarily overriding $ stdxxx will mix the output of the child processes.

+5
source share
4 answers

Why do you need to spawn? If you are not on Windows, you can use popen*, for example. popen4:

require "open4"

pid, p_i, p_o, p_e = Open4.popen4("ls")
p_i.close
o, e = [p_o, p_e].map { |p| begin p.read ensure p.close end }
s = Process::waitpid2(pid).last
+1
source

If you don't like popen, here is my way:

r, w = IO.pipe
pid = Process.spawn(command, :out => w, :err => [:child, :out]) 
w.close

...

pid, status = Process.wait2
output = r.read
r.close

String. -, , .

+4

The easiest and easiest way seems

require 'open3'

out, err, ps = Open3.capture3("ls")

puts "Process failed with status #{ps.exitstatus}" unless ps.success?

Here we have outputs as strings.

+1
source

From the Ruby docs, it seems you can't, but you can do it:

spawn("ls", 0 => ["/tmp/ruby_stdout_temp", "w"])
stdoutStr=File.read("/tmp/ruby_stdout_temp")

You can also do the same with a standard error. Or, if you do not and do not mind popen:

io=IO.popen("ls")
stdout=io.read
0
source

All Articles