Ruby,exec,system和%x()或反引号之间的区别
以下Ruby方法有什么区别?
exec
, system
和%x()
或者Backticks
我知道他们是用来通过Ruby编程执行terminal命令,但我想知道为什么有三种不同的方式来做到这一点。
系统
system
方法调用一个系统程序。 您必须将此命令作为string参数提供给此方法。 例如:
>> system("date") Wed Sep 4 22:03:44 CEST 2013 => true
被调用的程序将使用Ruby程序的当前STDIN
, STDOUT
和STDERR
对象。 实际上,实际的回报值是true
, false
或nil
。 在这个例子中,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
调用另一个进程并将其退出值返回给当前进程。 使用反引号调用另一个进程, 并将该进程的输出返回到当前进程。