Ruby,exec、system 和 %x() 或反引号之间的区别 [英] Ruby, Difference between exec, system and %x() or Backticks
问题描述
以下 Ruby 方法有什么区别?
What is the difference between the following Ruby methods?
exec
、system
和 %x()
或 反引号
我知道它们用于通过 Ruby 以编程方式执行终端命令,但我想知道为什么有三种不同的方法来执行此操作.
I know they are used to execute terminal commands programmatically via Ruby, but I'd like to know why there are three different ways to do this.
推荐答案
系统
系统
方法调用系统程序.您必须将此命令作为字符串参数提供给此方法.例如:
The system
method calls a system program. You have to provide the command as a string argument to this method. For example:
>> system("date")
Wed Sep 4 22:03:44 CEST 2013
=> true
被调用的程序将使用您的 Ruby 程序当前的 STDIN
、STDOUT
和 STDERR
对象.实际上,实际的返回值是true
、false
或nil
.在示例中,日期是通过 STDIN
的 IO 对象打印的.如果进程以零状态退出,该方法将返回 true
,如果进程以非零状态退出,则返回 false
,如果进程以非零状态退出,则返回 nil
执行失败.
The invoked program will use the current STDIN
, STDOUT
and STDERR
objects of your Ruby program. In fact, the actual return value is either true
, false
or nil
. In the example the date was printed through the IO object of STDIN
. The method will return true
if the process exited with a zero status, false
if the process exited with a non-zero status and nil
if the execution failed.
从 Ruby 2.6 开始,传递 exception: true
将引发异常而不是返回 false
或 nil
:
As of Ruby 2.6, passing exception: true
will raise an exception instead of returning false
or nil
:
>> system('invalid')
=> nil
>> system('invalid', exception: true)
Traceback (most recent call last):
...
Errno::ENOENT (No such file or directory - invalid)
另一个副作用是全局变量 $?
设置为 Process::Status
对象.该对象将包含有关调用本身的信息,包括被调用进程的进程标识符 (PID) 和退出状态.
Another side effect is that the global variable $?
is set to a Process::Status
object. This object will contain information about the call itself, including the process identifier (PID) of the invoked process and the exit status.
>> system("date")
Wed Sep 4 22:11:02 CEST 2013
=> true
>> $?
=> #<Process::Status: pid 15470 exit 0>
反引号
反引号 (``) 调用系统程序并返回其输出.与第一种方法相反,该命令不是通过字符串提供的,而是通过将其放在反引号对中来提供的.
Backticks (``) call a system program and return its output. As opposed to the first approach, the command is not provided through a string, but by putting it inside a backticks pair.
>> `date`
=> Wed Sep 4 22:22:51 CEST 2013
全局变量 $?
也是通过反引号设置的.使用反引号,您还可以使用字符串插值.
The global variable $?
is set through the backticks, too. With backticks you can also make use string interpolation.
%x()
使用 %x
是反引号样式的替代方法.它也会返回输出.就像它的亲戚 %w
和 %q
(以及其他)一样,只要括号样式的分隔符匹配,任何分隔符就足够了.这意味着 %x(date)
、%x{date}
和 %x-date-
都是同义词.像反引号 %x
可以利用字符串插值.
Using %x
is an alternative to the backticks style. It will return the output, too. Like its relatives %w
and %q
(among others), any delimiter will suffice as long as bracket-style delimiters match. This means %x(date)
, %x{date}
and %x-date-
are all synonyms. Like backticks %x
can make use of string interpolation.
执行
通过使用 Kernel#exec
当前进程(您的 Ruby 脚本)被替换为通过 exec
调用的进程.该方法可以将字符串作为参数.在这种情况下,字符串将受到外壳扩展.当使用多个参数时,则使用第一个参数执行程序,并提供以下参数作为要调用的程序的参数.
By using Kernel#exec
the current process (your Ruby script) is replaced with the process invoked through exec
. The method can take a string as argument. In this case the string will be subject to shell expansion. When using more than one argument, then the first one is used to execute a program and the following are provided as arguments to the program to be invoked.
Open3.popen3
有时所需的信息会写入标准输入或标准错误,您也需要控制这些信息.这里 Open3.popen3
派上用场:
Sometimes the required information is written to standard input or standard error and you need to get control over those as well. Here Open3.popen3
comes in handy:
require 'open3'
Open3.popen3("curl http://example.com") do |stdin, stdout, stderr, thread|
pid = thread.pid
puts stdout.read.chomp
end
这篇关于Ruby,exec、system 和 %x() 或反引号之间的区别的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!