关于性能:何时使用Ruby中启动子进程的每个方法

When to use each method of launching a subprocess in Ruby

1。``倒勾

  • 在内核中定义

1。a)%x{}percent x

  • 在parse.y中定义,请参见讨论
  • 2。system()

    • 核心系统

    三。fork()

    • 内核叉,进程叉

    4。open()

    • 打开管道
    • 内核开放

    4.a.IO.popen()open()的行为相同。

    • 打开管道
    • 伊奥诺波彭

    4.B.open("|-")

    • 叉到管道

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

    • 叉到管道
    • 见讨论

    5。Open3.popen3()

    • require 'open3'
    • STDLIB Open3

    6。PTY.spawn()

    • require 'pty'
    • STDLIB PTY

    7。Shell.transact()

    • require 'shell'
    • STDLIB外壳

    对于一种更复杂的方法,什么时候应该放弃值得信赖的反勾号呢?

    编辑1。感谢Avdi Grimm的文章,他描述了每个方法的示例用法:1(&gist);2(&gist);3。

    它们是回答"如何"问题的绝佳资源,但并不是明确组成来回答每个问题应在何时使用或为什么使用,因此,imho并不是这个问题的完整答案。


  • 当您希望轻松捕获变量中程序的输出时,请使用反勾号。您可能只想将其用于短时间运行的程序,因为这会阻塞程序。

  • system在两种情况下都很方便:

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

    b.system可以绕过像exec那样的壳膨胀(比较system"echo *"system"echo","*"的输出)

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

  • fork也有几个不同的用例:

    a.您希望在单独的进程中运行一些Ruby代码(例如fork { .... })

    b.您希望在不阻塞脚本fork { exec"bash" }进度的情况下运行子进程(或其他程序)。

    如果你想监控你的程序,fork是你的朋友。

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

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

  • 当您希望生成的程序像从终端运行一样运行时,PTY.spawn是必需的。见systemPTY.spawn的差异。


  • 这是基于这个答案的流程图。另请参见,使用script模拟终端。

    enter image description here


    看看这个系列文章:

    • Ruby中启动子进程的十几种方法:第1部分
    • Ruby中启动子进程的十几种方法:第2部分
    • Ruby中启动子进程的十几种方法:第3部分