何时使用 Ruby 中启动子进程的每种方法
1. ``
反引号
- 在 内核
1. a) %x{}
百分比 X < 在 parse.y 中定义的反引号的替代语法
- ,请参阅 讨论
2. system()
3. fork ()
4. open()
- 打开管道
- Kernel#open
4.a。 IO.popen()
IO.popen()
IO.popen()
相同
- 行为与
open()
打开管道 - IO#popen
4.b。 open("|-")
- 分叉到管道
4.c. IO.popen("-")
< 行为相同
- 与
open("|-")
fork 到管道的 - ,请参阅
5. Open3.popen3()
require 'open3'
- stdlib Open3
6. PTY.spawn()
需要'pty'
- stdlib PTY
7. Shell.transact()
require 'shell'
- stdlib Shell
什么时候应该放弃可靠的反勾号以使用一种更复杂的方法?
编辑1。 非常感谢 Avdi Grimm 描述每种方法示例用法的帖子:#1 (& 要点); #2(& 要点); #3。
它们是回答如何的绝佳资源,但没有明确地回答何时使用或为什么,因此恕我直言,它们不是这个问题的完整答案。
1. ``
The Backtick
- defined in Kernel
1. a) %x{}
Percent X < alternate syntax for The Backtick
- defined in parse.y, see discussion
2. system()
3. fork()
4. open()
- open a pipe
- Kernel#open
4.a. IO.popen()
< behaves the same as open()
- open a pipe
- IO#popen
4.b. open("|-")
- fork to a pipe
4.c. IO.popen("-")
< behaves the same as open("|-")
- fork to a pipe
- see discussion
5. Open3.popen3()
require 'open3'
- stdlib Open3
6. PTY.spawn()
require 'pty'
- stdlib PTY
7. Shell.transact()
require 'shell'
- stdlib Shell
When should one forsake the trusty back-tick for one of the more complex methods?
Edit 1.
Big thanks to Avdi Grimm for his posts describing example usage of each method: #1 (& gist); #2 (& gist); #3.
They are fantastic resources to answer How, but are not explicitly composed to answer when each should be used or Why, and as such IMHO are not complete answers to this question.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
当您想要轻松捕获变量中的程序输出时,请使用反引号。您可能只想将其用于短期运行的程序,因为这会阻塞。
system
在两种不同的情况下很方便:a.您有一个长时间运行的程序,并且希望在运行时打印输出(例如
system("tar zxvf some_big_tarball.tar.gz")
)b.
system
可以像exec
一样绕过 shell 扩展(比较system "echo *"
和system "echo", "* “
)系统会阻塞,直到子进程退出。
fork
也有几个不同的用例:a.您想要在单独的进程中运行一些 ruby 代码(例如
fork { .... }
b.您希望运行子进程(或不同的程序)而不阻止脚本的进度
fork { exec "bash" }
。如果您想守护程序,
fork
是您的朋友。IO.popen
在您需要时很有用。与程序的标准输出和标准输入交互。它不会捕获标准错误,因此如果您关心的话,您需要使用2>&1
重定向它。popen3
为您提供一个单独的标准错误文件描述符(当您需要从标准输出中单独捕获该文件时)PTY.spawn
是必需的。查看使用system
生成时grep --color=auto pat file
与PTY.spawn
PTY 的区别
use backticks when you want to easily capture the output of a program in a variable. you probably only want to use this for short-running programs, because this will block.
system
is convenient in two different cases:a. You have a long running program and you want the output to print as it runs (e.g.
system("tar zxvf some_big_tarball.tar.gz")
)b.
system
can bypass the shell expansion likeexec
(compare the output ofsystem "echo *"
andsystem "echo", "*"
)system blocks until the subprocess has exited.
fork
has a couple different use cases as well:a. You want to run some ruby code in a separate process (e.g.
fork { .... }
b. You want to run a child process (or different program) without blocking progress of your script
fork { exec "bash" }
.fork
is your friend if you want to daemonize your program.IO.popen
is useful when you need to interact with the standard out and standard in of a program. Note that it doesn't capture standard err, so you need to redirect that with2>&1
if you care about that.popen3
gives you a separate file descriptor for standard error (for when you need to capture that separately from standard out)PTY.spawn
is necessary when you want the spawned program to behave like you are running from the terminal. See the difference ofgrep --color=auto pat file
when spawned withsystem
vsPTY.spawn
这是基于此答案的流程图。另请参阅使用
脚本
模拟终端。Here's a flowchart based on this answer. See also, using
script
to emulate a terminal.除了上面的流程图https://stackoverflow.com/a/30463900/1211266,以防有人想要它markdown 中的可编辑流程图(由 美人鱼),这里是:
In addition to the flowchart above https://stackoverflow.com/a/30463900/1211266, in case somebody wants it as an editable flowchart in markdown (powered by mermaid), here it is:
另外,还有 Process.spawn。来自文档:
Also, there is Process.spawn. From the docs: