Get specific level value of nested attributes


I want to loop for on Ohai [etc][passwd] attribute to get only user’s names (such as root, halt, shutdown, etc.) but using the code below I receive the nested attributes as well, such as uid, gid, gecos, etc.

node[:etc][:passwd].each do |user|
#Do Something based on username

How can I loop just on the usernames?




There are several things here to note. First, node attributes are referenced by convention with strings and not symbols. Symbols work, but I think this has been removed in Chef 13.
So node[‘etc’][‘passwd’] is what you want and since this is a hash itself, you have to give the block keys and values.
So your code could work like this:

node['etc']['passwd'].each do |user, attributes|
  puts "User is #{user}, with attributes #{attributes}"

But since you might only need the usernames which are the keys of the array there is, in Ruby, this nice thing:

node['etc']['passwd'].keys.each do |user|
  puts "user is #{user}"
node['etc']['passwd'].each_key do |user| # The same as above
  puts "user is #{user}"


Hi joerg,
your response is perfect.

Thanks a lot and best regards