$ irb
>> warning = `perl -e "warn 'dust in the wind'"`
dust in the wind at -e line 1.
=> ""
>> puts warning
=> nil
可以看出,warning并没有得到出错的信息,这就表明反引号无法得到标准错误的信息。
IO#popen
IO#popen也是一种执行命令的方法,其命令也是在另外的进程中执行。使用popen你可以像操作IO对象一样处理标准输入和输出。
$ irb
>> IO.popen("date") { |f| puts f.gets }
Mon Mar 12 18:58:56 PDT 2007
=> nil
Open3#popen3
在标准的Ruby库中还提供了一个Open3。使用这个类我们可以很容易的对标准输入,输出,错误进行处理。这里我们使用一个可以交互的工具dc。dc是一种逆波兰表达式(又叫做后缀表达式,每一运算符都置于其运算对象之后)的计算器,支持从标准输入读取数学表达式。在这个例子中,我们将两个数值和一个操作符进行压栈处理。然后使用p来输出结果。比如我们输入5和10,然后输入+,然后会得到15n的输出。
$ irb
>> stdin, stdout, stderr = Open3.popen3('dc')
=> [#<IO:0x6e5474>, #<IO:0x6e5438>, #<IO:0x6e53d4>]
>> stdin.puts(5)
=> nil
>> stdin.puts(10)
=> nil
>> stdin.puts("+")
=> nil
>> stdin.puts("p")
=> nil
>> stdout.gets
=> "15n"
使用这个方法,我们不仅可以读取到命令的输出还可以对命令进行输入操作。这个方法对于进行交互操作很方便。通过popen3,我们还可以得到标准的错误信息。
# (irb continued...)
>> stdin.puts("asdfasdfasdfasdf")
=> nil
>> stderr.gets
=> "dc: stack emptyn"
但是,在ruby 1.8.5中popen3有一个缺陷,进程的退出状态没有写入到$?中。
$ irb
>> require "open3"
=> true
>> stdin, stdout, stderr = Open3.popen3('false')
=> [#<IO:0x6f39c0>, #<IO:0x6f3984>, #<IO:0x6f3920>]
>> $?
=> #<Process::Status: pid=26285,exited(0)>
>> $?.to_i
=> 0
为什么是0,false命令执行后的退出状态应该是非0才对,由于这个缺陷,我们需要了解一下Open4
Open4#popen4
Open4#popen4使用起来和Open3#popen3差不多,而且我们也可以得到程序的退出状态。popen4还可以返回一个子进程ID。你也可以通过Process::waitpid2 加上对应的进程ID获得进程退出状态。但是前提是要安装open4的gem。










