Ruby,exec,system和%x()或反引号之间的区别

以下Ruby方法有什么区别?

execsystem%x()或者Backticks

我知道他们是用来通过Ruby编程执行terminal命令,但我想知道为什么有三种不同的方式来做到这一点。

系统

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

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

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

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

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

反引号

反引号 (“)调用一个系统程序并返回它的输出。 与第一种方法相反,命令不是通过string提供的,而是通过将其置于反引号对内来提供的。

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

全局variables$? 也是通过反引号设置的。 反引号你也可以使用string插值。

%X()

使用%x是反引号样式的替代方法。 它也会返回输出。 像它的亲属%w%q (等等),只要括号式分隔符匹配,任何分隔符就足够了。 这意味着%x(date)%x{date}%x-date-都是同义词。 像反引号%x可以使用string插值。

EXEC

通过使用Kernel#exec ,当前进程(您的Ruby脚本)被通过exec调用的进程replace。 该方法可以采用一个string作为参数。 在这种情况下,string将受到shell扩展。 当使用多个参数时,第一个参数被用来执行一个程序,下面的参数被作为参数提供给被调用的程序。

Open3.popen3

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

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

这是基于这个答案的stream程图。 另请参阅使用script来模拟terminal 。

在这里输入图像描述

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