【发布时间】:2020-08-18 09:33:21
【问题描述】:
我下面的代码示例运行一个命令,例如 ls <file> 并捕获 stdout 和 stderr(以及进程退出状态)。
但是,例如,如果命令挂起,那么 ruby 程序将“卡住”,等待命令完成(例如,如果运行 sleep,则可以看到这一点)。
为了避免这种可能性,我认为我需要做的是fork 一个子进程,(所以任何“卡住”的子进程都不会让 ruby 程序“等待”)。
但是,我不确定如何从分叉的子进程中捕获标准输出和标准错误,这是否可能?
(出于原因我还希望能够在 ruby 标准库中执行此操作,并且不依赖任何额外的 gem/s。 此外,这仅适用于 ruby,not rails )
编辑:帮助澄清 - 试图了解是否有办法分叉子进程,(因此在子进程完成之前不会阻塞),和仍然让 ruby 程序在子进程退出时捕获 stdout、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
【问题讨论】:
-
但是
stdout、stderr和status在孩子完成之前不能有有意义的值。 -
Open3.capture3 将阻塞直到孩子完成。
-
@twenty20,你能告诉我们你的程序在做什么但不起作用吗?
-
@MichaelChaney 我认为关键是 OP 想要一种方法来不阻止直到孩子完成。
-
@twenty20,您也可以使用线程来捕获输出。您的程序将不再是连续的,因为子进程将继续与您的主进程一起运行。您必须想办法知道子流程何时完成并收获/使用输出。这是一种非常不同的编程方式。
标签: ruby fork parent-child stdout stderr