Ruby,exec,system和%x()或Backticks之间的区别

时间:2011-06-14 03:59:14

标签: ruby exec

以下Ruby方法有什么区别?

execsystem%x()反引号

我知道它们用于通过Ruby以编程方式执行终端命令,但我想知道为什么有三种不同的方法来执行此操作。

3 个答案:

答案 0 :(得分:377)

<强>系统

system方法调用系统程序。您必须将此命令作为字符串参数提供给此方法。例如:

>> system("date")
Wed Sep 4 22:03:44 CEST 2013
=> true

调用的程序将使用Ruby程序的当前STDINSTDOUTSTDERR对象。实际上,实际返回值为truefalsenil。在示例中,日期是通过STDIN的IO对象打印的。如果进程以零状态退出,则该方法将返回true,如果进程退出非零状态,则返回false,如果执行失败,则返回nil

另一个副作用是全局变量$?设置为Process::Status对象。此对象将包含有关调用本身的信息,包括调用进程的进程标识符(PID)和退出状态。

>> system("date")
Wed Sep 4 22:11:02 CEST 2013
=> true
>> $?
=> #<Process::Status: pid 15470 exit 0>

<强>反引号

Backticks(``)调用系统程序并返回其输出。与第一种方法相反,该命令不是通过字符串提供的,而是通过将其放在反引号对中。

>> `date`
=> Wed Sep 4 22:22:51 CEST 2013   

全局变量$?也是通过反引号设置的。使用反引号,您还可以使用字符串插值。

<强>%×()

使用%x可以替代反引号样式。它也会返回输出。与其亲属%w%q(以及其他人)一样,只要括号样式的分隔符匹配,任何分隔符都可以。这意味着%x(date)%x{date}%x-date-都是同义词。像反引号一样%x可以使用字符串插值。

<强> EXEC

通过使用Kernel#exec,当前进程(您的Ruby脚本)将替换为通过exec调用的进程。该方法可以将字符串作为参数。在这种情况下,字符串将受到shell扩展。当使用多个参数时,第一个参数用于执行程序,并且以下提供作为要调用的程序的参数。

<强> Open3.popen3

有时,所需信息会写入标准输入或标准错误,您也需要控制这些信息。这里Open3.popen3派上用场了:

require 'open3'

Open3.popen3("curl http://example.com") do |stdin, stdout, stderr, thread|
   pid = thread.pid
   puts stdout.read.chomp
end

答案 1 :(得分:220)

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

enter image description here

答案 2 :(得分:100)

他们做不同的事情。 exec使用新流程替换当前流程,永不返回system调用另一个进程,将其退出值返回到当前进程。使用反引号调用另一个进程,将该进程的输出返回到当前进程。