Proceso hijo de horquilla con tiempo de espera y salida de captura

Digamos que tengo una función como la de abajo, ¿cómo capturo la salida de la llamada Process.spawn? También debería poder finalizar el proceso si demora más que un tiempo de espera especificado.

Tenga en cuenta que la función también debe ser multiplataforma (Windows / Linux).

def execute_with_timeout!(command) begin pid = Process.spawn(command) # How do I capture output of this process? status = Timeout::timeout(5) { Process.wait(pid) } rescue Timeout::Error Process.kill('KILL', pid) end end 

Gracias.

Puede usar IO.pipe y decirle a Process.spawn que use la salida redirigida sin la necesidad de una gem externa.

Por supuesto, solo comenzando con Ruby 1.9.2 (y personalmente recomiendo 1.9.3)

La siguiente es una implementación simple utilizada por Spinach BDD internamente para capturar tanto salidas como errores:

 # stdout, stderr pipes rout, wout = IO.pipe rerr, werr = IO.pipe pid = Process.spawn(command, :out => wout, :err => werr) _, status = Process.wait2(pid) # close write ends so we could read them wout.close werr.close @stdout = rout.readlines.join("\n") @stderr = rerr.readlines.join("\n") # dispose the read ends of the pipes rout.close rerr.close @last_exit_status = status.exitstatus 

La fuente original está en features / support / filesystem.rb

Es altamente recomendable que lea la propia documentación de Ruby Process.spawn .

Espero que esto ayude.

PD: dejé la implementación de tiempo de espera como tarea para ti 😉

Seguí el consejo de Anselm en su publicación en el foro de Ruby aquí .

La función se ve así:

 def execute_with_timeout!(command) begin pipe = IO.popen(command, 'r') rescue Exception => e raise "Execution of command #{command} unsuccessful" end output = "" begin status = Timeout::timeout(timeout) { Process.waitpid2(pipe.pid) output = pipe.gets(nil) } rescue Timeout::Error Process.kill('KILL', pipe.pid) end pipe.close output end 

Esto hace el trabajo, pero prefiero usar una gem de terceros que envuelve esta funcionalidad. ¿Alguien tiene mejores maneras de hacer esto? He intentado Terminator , hace exactamente lo que quiero pero parece que no funciona en Windows.

    Intereting Posts