Reputation: 59
My below code example runs a command, e.g., ls <file>
and captures stdout and stderr ( as well as the process exit status ).
However, if for example the command were to hang, then the ruby program will be "stuck" waiting for the command to finish, ( this can be seen for example if running sleep
).
To avoid that possibility, I think what I need to do is fork
a child process, ( so any "stuck" child process will not keep the ruby program "waiting" ).
However, I'm not sure how to capture the stdout and stderr from a forked child process, is this even possible ?
( for reasons I'd also like to be able to do this within the ruby std libs and not have dependency on any extra gem/s. Also, this is just for ruby, not rails )
edit: To help clarify - Trying to understand if there is a way to fork a child process, ( so there is no blocking until the child is done ), and still have the ruby program capture the stdout, stderr when the child process exits.
#!/bin/env ruby
require 'open3'
require 'logger'
logger = Logger.new('./test_open3.log')
files = ['file1','file2','file3']
files.each do |f|
stdout, stderr, status = Open3.capture3("ls #{f}")
logger.info(stdout)
logger.info(stderr)
logger.info(status)
end
Upvotes: 1
Views: 1019
Reputation: 59
Following the suggestion in the comments to use threads, I found that this gave me what I was looking for:
#!/bin/env ruby
require 'open3'
require 'logger'
require 'thread'
logger = Logger.new('./test_threads_open3.log')
files = ['file1','file2','file3']
threads = []
files.each_with_index do |f, i|
threads << Thread.new(f, i) do
puts "Thread #{i} is running"
stdout, stderr, status = Open3.capture3("ls #{f}")
logger.info(stdout)
logger.info(stderr)
logger.info(status)
end
end
threads.each { |t| t.join }
This creates an array of threads each with the block of code, and then last line, each thread in the array is run.
It probably requires some extra code to manage and limit the number of threads that can be run at a time, so as to be safer, maybe by using a queue/worker feature.
( This post also touches on the topic of the join
method - Thread.join blocks the main thread )
Upvotes: 1