Ruby 哈希未填充
Ruby Hash Not Populating
我在 Chef 工作,试图 create/populate 一个 ruby
网络设备信息散列,由 nmcli
填充。我认为代码是正确的,因为 VS Code
没有抱怨,而且 运行 在 chef-shell -z
中似乎很好,但我无法查询 Ruby 哈希正如我所料,我真的开始失去理智了。
感谢新鲜的眼睛和任何专家的帮助,谢谢!
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
的建议编辑代码时
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]}"
所以我试过了,但我仍然从哈希中得到了零响应。这是大厨 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)>
更新:2022 年 5 月 2 日,星期一 12:08 PST
当我执行此命令时,我可以看到哈希中有数据...但是所有实际查询数据的尝试都失败了...我不知道我做错了什么:
chef (17.6.18)> puts "#{interfaces}"
{"wifi"=>"wlp61s0", "ethernet"=>"enp0s31f6"}
=> nil
chef (17.6.18)>
下面这行代码returns将值存储在hsh中的键{"wifi" => "#{output.split(":")[0]}"}
下。它不执行任何分配,很可能 returns nil
.
interfaces["wifi" => "#{output.split(":")[0]}"]
您需要的是:
interfaces["wifi"] = "#{output.split(":")[0]}"
直接打电话
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 和以太网只有一键。因此,如果您有更多设备,将只使用最后一个值
因为你是 运行 Chef 中的这个,你可以使用 Ohai 收集的自动属性,而不是 运行 命令来获取它的 stdout
.
Ohai is a tool for collecting system configuration data, which it then provides to Chef Infra Client to use in cookbooks.
有关机器网络配置的综合详细信息存储在 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
并提供整个设备列表。
我在 Chef 工作,试图 create/populate 一个 ruby
网络设备信息散列,由 nmcli
填充。我认为代码是正确的,因为 VS Code
没有抱怨,而且 运行 在 chef-shell -z
中似乎很好,但我无法查询 Ruby 哈希正如我所料,我真的开始失去理智了。
感谢新鲜的眼睛和任何专家的帮助,谢谢!
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
的建议编辑代码时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]}"
所以我试过了,但我仍然从哈希中得到了零响应。这是大厨 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)>
更新:2022 年 5 月 2 日,星期一 12:08 PST
当我执行此命令时,我可以看到哈希中有数据...但是所有实际查询数据的尝试都失败了...我不知道我做错了什么:
chef (17.6.18)> puts "#{interfaces}"
{"wifi"=>"wlp61s0", "ethernet"=>"enp0s31f6"}
=> nil
chef (17.6.18)>
下面这行代码returns将值存储在hsh中的键{"wifi" => "#{output.split(":")[0]}"}
下。它不执行任何分配,很可能 returns nil
.
interfaces["wifi" => "#{output.split(":")[0]}"]
您需要的是:
interfaces["wifi"] = "#{output.split(":")[0]}"
直接打电话
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 和以太网只有一键。因此,如果您有更多设备,将只使用最后一个值
因为你是 运行 Chef 中的这个,你可以使用 Ohai 收集的自动属性,而不是 运行 命令来获取它的 stdout
.
Ohai is a tool for collecting system configuration data, which it then provides to Chef Infra Client to use in cookbooks.
有关机器网络配置的综合详细信息存储在 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
并提供整个设备列表。