Quizás esto ayude a alguien más que busque lograr una funcionalidad de tiempo de espera similar, pero necesita recolectar el salida del comando de shell.
He adaptado el método de @ shurikk para trabajar con Ruby 2.0 y algunos códigos de Fork child process with timeout and capture output para recopilar la salida.
def exec_with_timeout(cmd, timeout)
begin
# stdout, stderr pipes
rout, wout = IO.pipe
rerr, werr = IO.pipe
stdout, stderr = nil
pid = Process.spawn(cmd, pgroup: true, :out => wout, :err => werr)
Timeout.timeout(timeout) do
Process.waitpid(pid)
# close write ends so we can read from them
wout.close
werr.close
stdout = rout.readlines.join
stderr = rerr.readlines.join
end
rescue Timeout::Error
Process.kill(-9, pid)
Process.detach(pid)
ensure
wout.close unless wout.closed?
werr.close unless werr.closed?
# dispose the read ends of the pipes
rout.close
rerr.close
end
stdout
end
eso no es verdad. El subcuadro que ejecuta el comando debe terminar cuando finaliza el proceso primario de ruby. Por favor da un ejemplo más específico. –
@BenLee: el proceso principal no termina cuando expira el tiempo de espera. –
@ MladenJablanović, en un experimento rápido que hace. Creé un archivo ruby que no hizo más que: 'require 'timeout'; Timeout :: timeout (100) {'sleep 500'}'. Mientras lo ejecuto, hago 'ps aux | grep sleep' y ver el proceso de dormir. Luego envío SIGKILL al proceso de ruby, y nuevamente ejecuto 'ps aux | grep sleep' y ya no ve el proceso secundario. –