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

Mr.*_*ack 358 ruby exec

以下Ruby方法有什么区别?

exec,system%x()反引号

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

Kon*_*che 397

系统

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

>> system("date")
Wed Sep 4 22:03:44 CEST 2013
=> true
Run Code Online (Sandbox Code Playgroud)

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

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

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

反引号

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

>> `date`
=> Wed Sep 4 22:22:51 CEST 2013   
Run Code Online (Sandbox Code Playgroud)

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

%X()

使用%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
Run Code Online (Sandbox Code Playgroud)

  • 并且为了更细粒度地控制调用如何处理`STDIN`,`STDOUT`,`STDERR`,请考虑使用`Open3.popen3`; 例如,请参阅http://stackoverflow.com/a/10922097/258662 (3认同)

Ian*_*Ian 233

这是基于此答案的流程图.也参见,使用script以模拟终端.

在此输入图像描述

  • 这不是那么简单.在我的情况下,"可以(并且需要)阻止直到进程完成"然后使用popen3来检查STDOUT/STDERR输出. (2认同)
  • 典型的 StackOverflow - 每个人都很挑剔,但说实话,这个流程图非常方便,对我帮助很大。谢谢。 (2认同)

Wil*_*ell 102

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