Разветвить дочерний процесс и перехватить любой stdout и stderr? - PullRequest
0 голосов
/ 04 мая 2020

В приведенном ниже примере кода запускается команда, например, ls <file>, которая захватывает stdout и stderr (а также статус завершения процесса).

Однако, если, например, команда зависла, то ruby программа будет "зависать" в ожидании завершения команды sh (это видно, например, при запуске sleep).

Чтобы избежать такой возможности, я думаю, что мне нужно do - это fork дочерний процесс (поэтому любой "зависший" дочерний процесс не заставит программу ruby "ждать").

Однако я не уверен, как перехватить stdout и stderr возможно ли это из разветвленного дочернего процесса?

(по причинам Я также хотел бы иметь возможность делать это в библиотеках ruby std и не зависеть ни от каких дополнительные драгоценные камни / с. Кроме того, это только для ruby, , а не рельсы)

edit : чтобы помочь уточнить - пытается понять, если есть способ для раскрутки дочернего процесса (чтобы не было блокировки до завершения дочернего процесса), и по-прежнему ve ruby программа перехватывает стандартный вывод stderr при выходе из дочернего процесса.

#!/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

1 Ответ

0 голосов
/ 05 мая 2020

Следуя предложению в комментариях использовать потоки, я обнаружил, что это дало мне то, что я искал:

#!/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 }

Это создает массив потоков, каждый с блоком кода, а затем последний строка, каждый поток в массиве запускается.

Вероятно, требуется некоторый дополнительный код для управления и ограничения количества потоков, которые могут быть запущены одновременно, чтобы быть более безопасными, возможно, с помощью функции очереди / рабочего.

( Этот пост также касается топи c метода join - Thread.join блокирует основную тему )

...