以下Ruby方法之间有什么区别?

execsystem%x()Backticks

我知道它们被用来通过Ruby以编程方式执行终端命令,但我想知道为什么有三种不同的方法来实现这一点.

推荐答案

system

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

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

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

从Ruby 2.6开始,超过exception: true将引发异常,而不是返回falsenil:

>> system('invalid')
=> nil

>> system('invalid', exception: true)
Traceback (most recent call last):
...
Errno::ENOENT (No such file or directory - invalid)

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

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

Backticks

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

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

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

%x()

使用%x是backticks样式的另一种 Select .它也将返回输出.与它的亲属%w%q(以及其他人)一样,只要括号样式的分隔符匹配,任何分隔符都足够了.这意味着%x(date)%x{date}%x-date-都是同义词.像backticks %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

Ruby相关问答推荐

Ruby 中无法解释的撬动行为

删除带括号的子表达式

Ruby 按变量条件划分数组数组

Rubymine - 启用行号

创建一个哈希值作为数组和默认值作为空数组

GET 和 POST 请求的相同 Rails 4 路由

如何通过反射获取 Ruby 的 Module 类定义的常量?

如何在运行时判断 Ruby 中的 Gem 版本?

Ruby 和您必须使用 OpenSSL 支持重新编译 Ruby 或更改 Gemfile 中的源代码

为什么在 ruby​​ / rails / activerecord 中并不总是需要 self ?

文字数字中的下划线是什么意思?

使用哈希参数进行 DRY Ruby 初始化

Ruby:将字符串转换为日期

Ruby:除非与如果不是

在 Ruby 中, coerce() 是如何工作的?

Ruby on Rails switch

Capybara:按值而不是文本 Select 选项

使用 Liquid 标记在 Jekyll 中获取今天的日期

更好的 ruby​​ markdown 解释器?

Eclipse 的首选 Ruby 插件?