tags:

views:

35

answers:

3

This is my code for getting all system users:

 def get_all_system_users
  user_paths = Dir["#{ENV['HOME']}/../*"]
  users = user_paths.map { |path| path.split("..")[-1].gsub(/\W/, '') }
  users.select { |user| %x{id #{user}}.include?("uid") }
end

The problem is the id #{user} command which returns an output for inexistent users that bubbles all the way, exactly like a puts or pp.

How can I mute it but still evaluate the output of the command?

A: 

You may try to redirect the stderr to stdout (or dev/null), but it depends on your shell:

%x{id #{user} 2>&1}

..and you will need to detect when the utility returned a failure code:

if $?.success?
Arsen7
A: 

I'd prefer a more direct way: (EDIT: Updated to work with OSX, I think)

def get_all_system_users
  `dscacheutil -q user|grep name:|cut -d: -f2`.split
end

Or, to handle multiple OSes:

require 'rbconfig'

def get_all_system_users
  case RbConfig::CONFIG['host_os']
    when /mac|darwin/i
      `dscacheutil -q user|grep name:|cut -d: -f2`.split
    when /linux/i
      `cat /etc/passwd|grep "/home"|cut -d: -f1`.split
    else
      raise "InferiorOS Error" #or whatever
  end
end
Mark Thomas
A: 

It's easier to just parse the /etc/passwd file:

Hash[File.readlines('/etc/passwd').map { |line|
       line.split ':'
     }.select { |field|
       field[5].index('/home/') == 0 && File.directory?(field[5])
     }.map { |field|
       [field[0], field[2].to_i]
     }]

This will return a hash with username as key and uid as value for all users with an existing home directory under /home/.

Lars Haugseth