首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用于nil的Ruby未定义方法‘[]:NilClass

用于nil的Ruby未定义方法‘[]:NilClass
EN

Stack Overflow用户
提问于 2016-10-19 10:36:11
回答 2查看 744关注 0票数 0

我试图让nagios检查BBU (电池备份单元),我有一个名为check_bbu的红宝石脚本

代码语言:javascript
复制
#!/usr/bin/ruby
require 'json'

output = %x{/usr/sbin/storcli /c0/bbu show j}

begin
        j = JSON.parse(output)
        result = j["Controllers"][0]["Command Status"]["Status"]
        status = j["Controllers"][0]["Response Data"]["BBU_Info"][0]["State"]
rescue Exception => e
        puts "CRITICAL: error reading BBU status: #{e}"
        exit 2
end

if result != 'Success'
        puts "CRITICAL: command not successful, result: #{result}"
        exit 2
end

if status != 'Optimal'
        puts "CRITICAL: BBU not optimal, status is #{status}"
        exit 2
end

puts "OK: BBU is optimal"

但是当我运行这个插件时,我会得到以下错误,

代码语言:javascript
复制
$ ./check_nrpe -u -t 30 -H foo.example.com -c check_bbu
CRITICAL: error reading BBU status: undefined method `[]' for nil:NilClass

我在做什么错事?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-10-19 11:42:01

例如,对于我的评论,让我们想象一下我们有正确的JSON:

代码语言:javascript
复制
j = {"Controllers" => [{"Comand Status" => {"status" => 'ok'}}]}
=> {"Controllers"=>[{"Comand Status"=>{"status"=>"ok"}}]} 

因此,通过键入第一行,它应该返回正确的结果:

代码语言:javascript
复制
> j["Controllers"][0]["Comand Status"]["status"]
=> "ok" 

但是,您也可能出错JSON,例如:

代码语言:javascript
复制
j_e = {"Controllers" => []}

所以现在是返回错误:

代码语言:javascript
复制
>j_e["Controllers"][0]["Comand Status"]["status"]
NoMethodError: undefined method `[]' for nil:NilClass

要解决这个问题,您可以使用以下内容:

代码语言:javascript
复制
def try data, keys # there we take arguments: data == j, and keys == array with keys
  return data if data.nil? # there we check: if data, that we send == nil, for example j = nil, array = ['first', etc..] we should stop this method and return nil as result
  value = data[keys.shift] # on this line we try to get some data from j ##keys.shift will delete first element from array that we send to this method and return as `key` for `data`, for example data['Controllers'] so keys now will looks like: [0, 'Comand Status', 'status']
  unless keys.empty? #on this line we check if on the pred line we was used the last key and keys now looks like: [] we: *return value and if it's not empty we just **call this method 1 more time
    try(value, keys) #**value = [{"Comand Status" => {"status" => 'ok'}}] and keys = [0, 'Comand Status', 'status']
  else
    value #*nil or value
  end
end



j = {"Controllers"=>[{"Comand Status"=>{"status"=>"ok"}}]}
try(j, ['Controllers', 0, 'Comand Status', 'status'])
>'ok'
try j, ['Controllers', 1, 'Comand Status', 'status']
> nil

在您的代码中,应该如下所示:

代码语言:javascript
复制
require 'json'

def try data, keys
  return data if data.nil?
  value = data[keys.shift]  
  unless keys.empty?
    try(value, keys)
  else
    value
  end
end


output = %x{/usr/sbin/storcli /c0/bbu show j}
begin
  j = JSON.parse(output)
  result = try(j, ["Controllers", 0, "Command Status", "Status"])
  status = try(j, ["Controllers", 0, "Response Data", "BBU_Info", 0, "State"])
rescue Exception => e
  puts "CRITICAL: error reading BBU status: #{e}"
  exit 2
end

if result != 'Success'
  puts "CRITICAL: command not successful, result: #{result}"
  exit 2
end

if status != 'Optimal'
  puts "CRITICAL: BBU not optimal, status is #{status}"
  exit 2
end

puts "OK: BBU is optimal"

另外,对于Ruby 2.3.0+

简单多了,只是:

代码语言:javascript
复制
j.dig("Controllers", 0, "Comand Status", "status")
票数 1
EN

Stack Overflow用户

发布于 2016-10-19 10:50:08

似乎你的代码在

代码语言:javascript
复制
j = JSON.parse(output)
result = j["Controllers"][0]["Command Status"]["Status"]
status = j["Controllers"][0]["Response Data"]["BBU_Info"][0]["State"]

你应该检查哪一行

  1. j == nil和你想要的j["Controllers"]
  2. result = j["Controllers"][0]["Command Status"]["Status"]
  3. status = j["Controllers"][0]["Response Data"]["BBU_Info"][0]["State"]

首先显示undefined method '[]' for nil:NilClass值,并确保json格式与您的代码匹配。

代码语言:javascript
复制
j = JSON.parse(output)
p j # display value

最新情况:

您的json格式应该与您的代码匹配,否则会引发错误。

例如:

代码语言:javascript
复制
{
  "Controllers": [
    {
      "Commandddd Status": { # format not match
        "Status": "success"
      }
    }
  ]
}

# code and json format not match
j["Controllers"][0]["Command Status"] # nil

j["Controllers"][0]["Command Status"]["Status"]
=> nil["Status"] #  boom!
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/40128958

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档