何时使用在 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
什么时候应该放弃值得信赖的反引号,转而使用一种更复杂的方法?
system()
fork()
open()
IO.popen()
open() 相同
open("|-")
IO.popen("-")
open("|-") 相同
Open3.popen3()
PTY.spawn()
Shell.transact()
编辑 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 file
与system
与PTY.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 中启动子进程的每种方法的主要内容,如果未能解决你的问题,请参考以下文章