代码之家  ›  专栏  ›  技术社区  ›  misteralexander

Ruby哈希未填充

  •  0
  • misteralexander  · 技术社区  · 2 年前

    我在Chef工作,试图创建/填充 ruby 网络设备信息的散列,由 nmcli 。我认为代码是正确的,因为 VS Code 没有抱怨,而且似乎运行得很好 chef-shell -z 但我无法像预期的那样查询Ruby Hash,我真的开始失去理智了。

    非常感谢新鲜的眼睛和任何专家的帮助,谢谢!

    interfaces = Hash.new
    #DEVICE,TYPE
    dev = Mixlib::ShellOut.new("nmcli -terse -field device,type device").run_command.stdout.split(/\n/)
    dev.each do |output|
      if "#{output.split(":")[1]}" == 'ethernet'
        interfaces["ethernet" => "#{output.split(":")[0]}"]
      elsif "#{output.split(":")[1]}" == 'wifi'
        interfaces["wifi" => "#{output.split(":")[0]}"]
      else
        Chef::Log.debug("Interface #{output.split(":")} is not supported")
      end
    end
    chef (17.6.18)>  
     => ["wlp61s0:wifi", "enp0s31f6:ethernet", "lo:loopback"] 
    node[interfaces] #nil
    node[:interfaces] #nil
    node['interfaces'] #nil
    node["interfaces"] #nil
    

    当我尝试编辑代码时,如 BroiSatse

    这一行 interfaces["wifi" => "#{output.split(":")[0]}"] 返回存储在密钥下的哈希中的值 {"wifi" => "#>{output.split(":")[0]}"} 。它不执行任何分配,并且大多数>可能回报为零。

    您需要的是:

    interfaces["wifi"] ="#{output.split(":")[0]}"

    所以我尝试了一下,但哈希仍然没有响应。以下是厨师输出/错误:

    chef (17.6.18)> interfaces = Hash.new
    chef > #DEVICE,TYPE
    chef (17.6.18)> dev = Mixlib::ShellOut.new("nmcli -terse -field device,type device").run_command.stdout.split(/\n/)
     => ["wlp61s0:wifi", "enp0s31f6:ethernet", "lo:loopback"] 
    chef > dev.each do |output|
    chef >   if "#{output.split(":")[1]}" == 'ethernet'
    chef >     interfaces["ethernet"] = "#{output.split(":")[0]}"
    chef >   elsif "#{output.split(":")[1]}" == 'wifi'
    chef >     interfaces["wifi"] = "#{output.split(":")[0]}"
    chef >   else
    chef >     Chef::Log.debug("Interface #{output.split(":")} is not supported")
    chef >   end
    chef (17.6.18)> end
     => ["wlp61s0:wifi", "enp0s31f6:ethernet", "lo:loopback"] 
    chef (17.6.18)> node[interfaces] #nil
     => nil 
    chef (17.6.18)> node[:interfaces][:ethernet] #nil
    (irb):95:in `<main>': undefined method `[]' for nil:NilClass (NoMethodError)
        from /opt/chef/embedded/lib/ruby/gems/3.0.0/gems/chef-17.6.18/lib/chef/shell.rb:93:in `block in start'
        from /opt/chef/embedded/lib/ruby/gems/3.0.0/gems/chef-17.6.18/lib/chef/shell.rb:92:in `catch'
        from /opt/chef/embedded/lib/ruby/gems/3.0.0/gems/chef-17.6.18/lib/chef/shell.rb:92:in `start'
        from /opt/chef/embedded/lib/ruby/gems/3.0.0/gems/chef-bin-17.6.18/bin/chef-shell:31:in `<top (required)>'
        from /usr/bin/chef-shell:158:in `load'
        from /usr/bin/chef-shell:158:in `<main>'
    chef (17.6.18)> node['interfaces'] #nil
    chef (17.6.18)> node["interfaces"] #nil
     => nil 
    chef (17.6.18)> 
    

    更新:2022年5月2日星期一太平洋标准时间12:08

    当我执行这个命令时,我可以看到哈希中有数据。。。但所有实际查询数据的尝试都失败了。。。我不知道自己做错了什么:

    chef (17.6.18)> puts "#{interfaces}"
    {"wifi"=>"wlp61s0", "ethernet"=>"enp0s31f6"}
     => nil 
    chef (17.6.18)> 
    
    1 回复  |  直到 2 年前
        1
  •  2
  •   mechnicov    2 年前

    只要打电话

    interfaces["ethernet"]
    

    interfaces["wifi"]
    
    interfaces = {}
    
    dev =
      Mixlib::ShellOut.new("nmcli -terse -field device,type device").
        run_command.
        stdout.
        lines(chomp: true)
    
    dev.each do |output|
      device, type_device = output.split(":")
    
      case type_device
      when "ethernet", "wifi"
        interfaces[type_device] = device
      else
        Chef::Log.debug("Interface #{output} is not supported")
      end
    end
    

    注意:将只有一个关键的wifi和以太网。所以,如果您有更多的设备,将只使用最后一个值

        2
  •  1
  •   seshadri_c    2 年前

    由于您在Chef中运行此功能,因此可以使用 Ohai ,而不是运行命令来获取 stdout

    Ohai是一个用于收集系统配置数据的工具,然后将其提供给Chef Infra Client,以便在烹饪书中使用。

    有关机器网络配置的全面详细信息存储在 node['network']['interfaces'] 搞砸

    在你的食谱中尝试一下,看看能捕捉到哪些细节:

    pp node['network']['interfaces']
    

    我们可以将这些自动属性与 select 过滤器以获取网络设备名称而不进行循环。

    interfaces = Hash.new
    
    # exclude any devices that don't have a "type", such as loopback
    ifaces = node['network']['interfaces'].select { |k, v| ! v['type'].nil? }
    
    # select device names for devices of type "en" (ethernet)
    interfaces['ethernet'] = ifaces.select { |k, v| v['type'].match(/^en/) }.keys.first
    
    # select device names for devices of type "wl" (wireless/wifi)
    interfaces['wifi'] = ifaces.select { |k, v| v['type'].match(/^wl/) }.keys.first
    

    上面的代码将获得匹配的“第一个”设备 en wl 分别地如果一种类型有多个设备,那么 .first 可以删除,并且整个设备列表将可用。

        3
  •  0
  •   Chris    2 年前

    下面的代码行返回存储在hsh键下的值 {"wifi" => "#{output.split(":")[0]}"} 。它不执行任何任务,很可能会返回 nil

    interfaces["wifi" => "#{output.split(":")[0]}"]
    

    您需要的是:

    interfaces["wifi"] = "#{output.split(":")[0]}"