我知道如何运行外部流程,因为有很多方法可以执行此操作。但是如何将其输出和退出代码捕获到变量?这些,最流行的流程运行方式,不能按我的意愿运作:
a = `ls -l` # "a" captures only output
b = system "ls -l " # "b" captures only exit code
答案 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非常清楚::popen3
。 stdout
提供了IO
个对象。因此,我们需要使用IO#read
方法。 wait_thr.value
给了我们Process::Status
。现在,一旦我们拥有了该对象,我们就可以使用#exitstatus
方法。