运行进程,捕获其输出并退出代码

时间:2014-08-06 03:17:45

标签: ruby

我知道如何运行外部流程,因为有很多方法可以执行此操作。但是如何将其输出退出代码捕获到变量?这些,最流行的流程运行方式,不能按我的意愿运作:

a = `ls -l` # "a" captures only output
b = system "ls -l " # "b" captures only exit code

5 个答案:

答案 0 :(得分:4)

最合适的是阅读$?.exitstatus

a = `ls -l`        # gets output
b = $?.exitstatus  # gets exit code

测试:

`true`
# => ""
$?.exitstatus
# => 0
`false`
# => ""
$?.exitstatus
# => 1
$?.class
# => Process::Status

有关处理退出状态的更多方法,请参阅Process::Status

答案 1 :(得分:1)

我会看一下popen4 gem,因为它会让你获得stout / stderr和退出状态。

另请参阅此页面,其中介绍了6 Ways to Run Shell Commands in Ruby,其中还详细介绍了popen4的用法。

status = Open4::popen4("false") do |pid, stdin, stdout, stderr|
    puts "stdout: #{stdout}" 
end
puts status

答案 2 :(得分:0)

#my_prog.rb
puts 'hello'
exit 10

...

require 'open3'

Open3.popen2("ruby my_prog.rb") do |stdin, stdout, wait_thr|
  puts stdout.read
  status_obj = wait_thr.value # Process::Status object returned.
  puts status_obj.exitstatus
end


--output:--
hello
10

答案 3 :(得分:0)

  

我希望异常作为类Exception的实例能够   重新提升它,而不仅仅是一个字符串。

你可以这样做:

#my_prog.rb

puts 'hello'
10/0

...

require 'open3'

begin
  Open3.popen3("ruby my_prog.rb") do |stdin, stdout, stderr, wait_thr|
    puts stdout.read
    status_obj = wait_thr.value  #Process::Status object returned.
    puts status_obj.exitstatus

    error = stderr.read
    md = error.match(/\w+ Error/xm)

    if md
      e = Exception.const_get(md[0]).new if md 
      p e.class.ancestors
      raise e
    end

  end
rescue ZeroDivisionError
  puts 'Hey, someone divided by zero!'
end

--output:--
hello
1
[ZeroDivisionError, StandardError, Exception, Object, Kernel, BasicObject]
Hey, someone divided by zero!

不幸的是,有几个例外,其名称并未以“错误”结尾 - 但您可以修改代码以在错误消息中专门搜索这些代码。

答案 4 :(得分:-1)

这是一种解决这个问题的方法。

#!/usr/bin/env ruby

require 'open3'

Open3.popen3("ls -l") do |stdin, stdout, stderr, wait_thr|
  puts stdout.read
  puts wait_thr.value.exitstatus 
end

# >> total 52
# >> -rw-r--r-- 1 arup users    0 Aug  5 09:32 a.rb
# >> drwxr-xr-x 2 arup users 4096 Jul 20 20:37 FSS
# >> drwxr-xr-x 2 arup users 4096 Jul 20 20:37 fss_dir
# >> -rw-r--r-- 1 arup users   42 Jul 19 01:36 out.txt
# .....
#...
# >> 0

Doco非常清楚::popen3stdout提供了IO个对象。因此,我们需要使用IO#read方法。 wait_thr.value给了我们Process::Status。现在,一旦我们拥有了该对象,我们就可以使用#exitstatus方法。