Ruby Hash不居住

发布于 2025-01-25 16:48:36 字数 3198 浏览 4 评论 0 原文

我在厨师中工作,试图创建/填充 Ruby Hash,并用网络设备信息,由 nmcli 填充。我认为代码是正确的,因为 vs代码没有抱怨,并且似乎在 Chef -Shell -Z 中运行良好,但我无法查询正如我所期望的那样的红宝石哈希,我真的开始失去理智。

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

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

这线 接口[“ wifi” => “#{output.split(“:”)[0]}” 返回在键下存储的值{“ wifi” => “#> {output.split(“:”)[0]}”} 。它没有执行任何作业,并且大多数gt;可能返回零。

您需要的是:

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日,星期一,

当我执行此命令时,我可以看到哈希中有数据...但是所有尝试实际查询数据失败的尝试... i不知道我做错了什么:

chef (17.6.18)> puts "#{interfaces}"
{"wifi"=>"wlp61s0", "ethernet"=>"enp0s31f6"}
 => nil 
chef (17.6.18)> 

I am working in Chef, trying to create/populate a ruby hash with networking device information, as populated by nmcli. I think the code is correct, as VS Code isn't complaining, and it seems to run just fine in chef-shell -z but I'm not able to query the Ruby Hash as I would expect, and I'm really starting to lose my mind.

Fresh eyes and any expert help here are appreciated, thank you!

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

When I attempt to edit the code, as suggested by BroiSatse

This line
interfaces["wifi" => "#{output.split(":")[0]}"]
returns the value stored in the hash under the key {"wifi" => "#>{output.split(":")[0]}"}. It does not perform any assignment and most > likely returns nil.

What you need is:

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

So I tried that, but I still get a nil response from the Hash. Here is the Chef output/error:

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)> 

UPDATE: Monday May 2, 2022 12:08 PST

When I do this command I can see that there is data in the Hash ... but all attempts to actually query the data fail ... I don't know what I'm doing wrong:

chef (17.6.18)> puts "#{interfaces}"
{"wifi"=>"wlp61s0", "ethernet"=>"enp0s31f6"}
 => nil 
chef (17.6.18)> 

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

溇涏 2025-02-01 16:48:36

只需致电

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和以太网。因此,如果您有更多设备,将使用最后一个值

Just call

interfaces["ethernet"]

or

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

Note: there will be just one key wifi and ethernet. So if you have more devices, just last value will be used

遗心遗梦遗幸福 2025-02-01 16:48:36

由于您正在厨师中运行此操作,因此您可以使用 stdout 。

ohai是用于收集系统配置数据的工具,然后它为厨师clief client提供在食谱中。

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

在您的食谱中尝试此信息以查看捕获的详细信息:

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

我们可以将这些自动属性与选择过滤器结合使用,以获取网络设备名称而无需循环。

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 ,并且可以使用整个设备列表。

Since you are running this in Chef, you can use automatic attributes collected by Ohai, instead of running command to get its stdout.

Ohai is a tool for collecting system configuration data, which it then provides to Chef Infra Client to use in cookbooks.

Comprehensive details about the machine's network configuration are stored under node['network']['interfaces'] hash.

Try this in your recipe to see what details are captured:

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

We can use these automatic attributes in combination with the select filter to get the network device names without looping.

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

The above code will get the "first" device that matches en or wl respectively. If there are multiple devices of a type, then .first can be removed and the entire list of devices will be available.

つ低調成傷 2025-02-01 16:48:36

以下代码行返回键 {“ wifi” =&gt下的HSH中存储的值; “#{output.split(“:”)[0]}”} 。它没有执行任何作业,很可能返回 nil

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

您需要的是:

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

The following line of code returns the value stored in the hsh under the key {"wifi" => "#{output.split(":")[0]}"}. It does not perform any assignment and most likely returns nil.

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

What you need is:

interfaces["wifi"] = "#{output.split(":")[0]}"
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文