何时使用在 Ruby 中启动子进程的每种方法

Posted

技术标签:

【中文标题】何时使用在 Ruby 中启动子进程的每种方法【英文标题】:When to use each method of launching a subprocess in Ruby 【发布时间】:2011-11-04 23:15:30 【问题描述】:

1。 `` 反引号

在Kernel中定义

1。 a) %x Percent X 在 parse.y 中定义,见 discussion

2。 system()

Kernel#system

3。 fork()

Kernel#fork, Process#fork

4。 open()

打开管道 Kernel#open

4.a. IO.popen() open() 相同

打开管道 IO#popen

4.b。 open("|-")

分叉到管道

4.c。 IO.popen("-") open("|-") 相同

分叉到管道 见discussion

5。 Open3.popen3()

require 'open3' 标准库Open3

6。 PTY.spawn()

require 'pty' 标准库PTY

7。 Shell.transact()

require 'shell' 标准库Shell

什么时候应该放弃值得信赖的反引号,转而使用一种更复杂的方法?

编辑 1. 非常感谢 Avdi Grimm 他的帖子描述了每种方法的示例用法:#1 (& gist); #2(&gist); #3.

它们是回答如何的绝佳资源,但没有明确组成回答何时应该使用它们为什么,因此恕我直言,这不是这个问题的完整答案。

【问题讨论】:

+1 信息性问题 :) 流程图是回答这个问题的最佳方式吗? 【参考方案1】:

    当您想在变量中轻松捕获程序的输出时,请使用反引号。您可能只想将它用于短期运行的程序,因为这会阻塞。

    system 在两种不同的情况下很方便:

    一个。您有一个长时间运行的程序,并且您希望在运行时打印输出(例如system("tar zxvf some_big_tarball.tar.gz")

    b. system 可以绕过像exec 这样的shell 扩展(比较system "echo *"system "echo", "*" 的输出)

    系统阻塞,直到子进程退出。

    fork 也有几个不同的用例:

    一个。您想在单独的进程中运行一些 ruby​​ 代码(例如 fork ....

    b.您想运行子进程(或不同的程序)而不阻塞脚本的进度fork exec "bash"

    fork 是你的朋友,如果你想守护你的程序。

    IO.popen 在您需要与程序的标准输出和标准输入交互时很有用。请注意,它不会捕获标准错误,因此如果您关心它,您需要使用 2>&1 重定向它。

    popen3 为您提供一个单独的标准错误文件描述符(当您需要从标准输出中单独捕获它时)

    PTY.spawn 在您希望生成的程序表现得像从终端运行时是必需的。查看grep --color=auto pat filesystemPTY.spawn 生成时的区别

【讨论】:

【参考方案2】:

这是基于this answer 的流程图。另请参阅using script to emulate a terminal。

【讨论】:

很好的答案你是如何制作这个流程图的?【参考方案3】:

看看这个系列文章:

A dozen (or so) ways to start sub-processes in Ruby: Part 1 A dozen (or so) ways to start sub-processes in Ruby: Part 2 A dozen (or so) ways to start sub-processes in Ruby: Part 3

【讨论】:

感谢您的链接,迈克尔。我已将这些添加到问题中。但是,根据我的阅读,他们回答 How 而不是 When 使用每个。 恕我直言,他们通过解释各种方法如何与 stdin、stdout 和 stderr 交互来回答这两个问题,这些文章可帮助您根据需要决定使用哪种方法。关心某事的返回值?反引号它是。你想并行运行东西,去fork。无论如何,我 +1 你的问题并等待答案,他们可能会很有趣! :-)

以上是关于何时使用在 Ruby 中启动子进程的每种方法的主要内容,如果未能解决你的问题,请参考以下文章

使用 Python 跟踪进程状态

检测子进程何时等待输入

2子进程的创建与启动

2子进程的创建与启动

何时对 Python 子进程模块使用 Shell=True [重复]

ruby 等待所有分叉的子进程完成