How to list all users in a Linux group?

LinuxUnix

Linux Problem Overview


How do I list all members of a group in Linux (and possibly other unices)?

Linux Solutions


Solution 1 - Linux

getent group <groupname>;

It is portable across both Linux and Solaris, and it works with local group/password files, NIS, and LDAP configurations.

Solution 2 - Linux

Unfortunately, there is no good, portable way to do this that I know of. If you attempt to parse /etc/group, as others are suggesting, you will miss users who have that group as their primary group and anyone who has been added to that group via a mechanism other than UNIX flat files (i.e. LDAP, NIS, pam-pgsql, etc.).

If I absolutely had to do this myself, I'd probably do it in reverse: use id to get the groups of every user on the system (which will pull all sources visible to NSS), and use Perl or something similar to maintain a hash table for each group discovered noting the membership of that user.

Edit: Of course, this leaves you with a similar problem: how to get a list of every user on the system. Since my location uses only flat files and LDAP, I can just get a list from both locations, but that may or may not be true for your environment.

Edit 2: Someone in passing reminded me that getent passwd will return a list of all users on the system including ones from LDAP/NIS/etc., but getent group still will still miss users that are members only via the default group entry, so that inspired me to write this quick hack.


#!/usr/bin/perl -T





Lists members of all groups, or optionally just the group


specified on the command line




Copyright © 2010-2013 by Zed Pobre ([email protected] or [email protected])




Permission to use, copy, modify, and/or distribute this software for any


purpose with or without fee is hereby granted, provided that the above


copyright notice and this permission notice appear in all copies.





use strict; use warnings;




$ENV{"PATH"} = "/usr/bin:/bin";




my $wantedgroup = shift;




my %groupmembers;
my $usertext = getent passwd;




my @users = $usertext =~ /^([a-zA-Z0-9_-]+):/gm;




foreach my $userid (@users)
{
my $usergrouptext = id -Gn $userid;
my @grouplist = split(' ',$usergrouptext);



foreach my $group (@grouplist)
{
    $groupmembers{$group}->{$userid} = 1;
}




}




if($wantedgroup)
{
print_group_members($wantedgroup);
}
else
{
foreach my $group (sort keys %groupmembers)
{
print "Group ",$group," has the following members:\n";
print_group_members($group);
print "\n";
}
}




sub print_group_members
{
my ($group) = @_;
return unless $group;



foreach my $member (sort keys %{$groupmembers{$group}})
{
    print $member,"\n";
}




}

}

Solution 3 - Linux

Use Python to list groupmembers:

> python -c "import grp; print grp.getgrnam('GROUP_NAME')[3]"

See https://docs.python.org/2/library/grp.html

Solution 4 - Linux

lid -g groupname | cut -f1 -d'(' 

Solution 5 - Linux

The following command will list all users belonging to <your_group_name>, but only those managed by /etc/group database, not LDAP, NIS, etc. It also works for secondary groups only, it won't list users who have that group set as primary since the primary group is stored as GID (numeric group ID) in the file /etc/passwd.

grep <your_group_name> /etc/group

Solution 6 - Linux

The following command will list all users belonging to <your_group_name>, but only those managed by /etc/group database, not LDAP, NIS, etc. It also works for secondary groups only, it won't list users who have that group set as primary since the primary group is stored as GID (numeric group ID) in the file /etc/passwd.

awk -F: '/^groupname/ {print $4;}' /etc/group

Solution 7 - Linux

The following shell script will iterate through all users and print only those user names which belong to a given group:

#!/usr/bin/env bash
getent passwd | while IFS=: read name trash
do
    groups $name 2>/dev/null | cut -f2 -d: | grep -i -q -w "$1" && echo $name
done
true

Usage example:

./script 'DOMAIN+Group Name'

Note: This solution will check NIS and LDAP for users and groups (not only passwd and group files). It will also take into account users not added to a group but having group set as primary group.

Edit: Added fix for rare scenario where user does not belong to group with the same name.

Edit: written in the form of a shell script; added true to exit with 0 status as suggested by @Max Chernyak aka hakunin; discarded stderr in order to skip those occasional groups: cannot find name for group ID xxxxxx.

Solution 8 - Linux

You can do it in a single command line:

cut -d: -f1,4 /etc/passwd | grep $(getent group <groupname> | cut -d: -f3) | cut -d: -f1

Above command lists all the users having groupname as their primary group

If you also want to list the users having groupname as their secondary group, use following command

getent group <groupname> | cut -d: -f4 |  tr ',' '\n'

Solution 9 - Linux

just a little grep and tr:

$ grep ^$GROUP /etc/group | grep -o '[^:]*$' | tr ',' '\n'
user1
user2
user3

Solution 10 - Linux

Zed's implementation should probably be expanded to work on some of the other major UNIX.

Someone have access to Solaris or HP-UX hardware?; did not test those cases.

#!/usr/bin/perl
#
# Lists members of all groups, or optionally just the group
# specified on the command line
#
# Date:         12/30/2013
# Author:       William H. McCloskey, Jr.
# Changes:      Added logic to detect host type & tailor subset of getent (OSX)
# Attribution:
#   The logic for this script was directly lifted from Zed Pobre's work.
#     See below for Copyright notice.
#   The idea to use dscl to emulate a subset of the now defunct getent on OSX
#     came from
#       http://zzamboni.org/\
#         brt/2008/01/21/how-to-emulate-unix-getent-with-macosxs-dscl/
#     with an example implementation lifted from
#       https://github.com/petere/getent-osx/blob/master/getent
#
# Copyright © 2010-2013 by Zed Pobre ([email protected] or [email protected])
#
# Permission to use, copy, modify, and/or distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
# copyright notice and this permission notice appear in all copies.
#

use strict; use warnings;

$ENV{"PATH"} = "/usr/bin:/bin";

# Only run on supported $os:
my $os;
($os)=(`uname -a` =~ /^([\w-]+)/);
unless ($os =~ /(HU-UX|SunOS|Linux|Darwin)/)
    {die "\$getent or equiv. does not exist:  Cannot run on $os\n";}

my $wantedgroup = shift;

my %groupmembers;

my @users;

# Acquire the list of @users based on what is available on this OS:
if ($os =~ /(SunOS|Linux|HP-UX)/) {
    #HP-UX & Solaris assumed to be like Linux; they have not been tested.
    my $usertext = `getent passwd`;
    @users = $usertext =~ /^([a-zA-Z0-9_-]+):/gm;
};
if ($os =~ /Darwin/) {
    @users = `dscl . -ls /Users`;
    chop @users;
}

# Now just do what Zed did - thanks Zed.
foreach my $userid (@users)
{
    my $usergrouptext = `id -Gn $userid`;
    my @grouplist = split(' ',$usergrouptext);

    foreach my $group (@grouplist)
    {
        $groupmembers{$group}->{$userid} = 1;
    }
}

if($wantedgroup)
{
    print_group_members($wantedgroup);
}
else
{
    foreach my $group (sort keys %groupmembers)
    {
        print "Group ",$group," has the following members:\n";
        print_group_members($group);
        print "\n";
    }
}

sub print_group_members
{
    my ($group) = @_;
    return unless $group;

    foreach my $member (sort keys %{$groupmembers{$group}})
    {
        print $member,"\n";
    }
}

If there is a better way to share this suggestion, please let me know; I considered many ways, and this is what I came up with.

Solution 11 - Linux

I've done this similar to the perl code above, but replaced getent and id with native perl functions. It is much faster and should work across different *nix flavors.

#!/usr/bin/env perl

use strict;
my $arg=shift;
my %groupMembers; # defining outside of function so that hash is only built once for multiple function calls

sub expandGroupMembers{
my $groupQuery=shift;
unless (%groupMembers){
    while (my($name,$pass,$uid,$gid,$quota,$comment,$gcos,$dir,$shell,$expire)=getpwent()) {
            my $primaryGroup=getgrgid($gid);
            $groupMembers{$primaryGroup}->{$name}=1;
    }
    while (my($gname,$gpasswd,$gid,$members)=getgrent()) {
            foreach my $member (split / /, $members){
                    $groupMembers{$gname}->{$member}=1;
            }
    }
}
my $membersConcat=join(",",sort keys %{$groupMembers{$groupQuery}});
return "$membersConcat" || "$groupQuery Does have any members";
}
print &expandGroupMembers($arg)."\n";

Solution 12 - Linux

There is a handy Debian and Ubuntu package called 'members' that provides this functionality:

> Description: Shows the members of a group; by default, all members members is the complement of groups: whereas groups shows the groups a specified user belongs to, members shows users belonging to a specified group.

> ... You can ask for primary members, secondary members, both on one line, each on separate lines.

Solution 13 - Linux

getent group insert_group_name_here | awk -F ':' '{print $4}' | sed 's|,| |g'

This returns a space separated list of users which I've used in scripts to populate arrays.

for i in $(getent group ftp | awk -F ':' '{print $4}' | sed 's|,| |g')
    do
        userarray+=("$i")
    done

or

userarray+=("$(getent group GROUPNAME | awk -F ':' '{print $4}' | sed 's|,| |g')")

Solution 14 - Linux

getent group groupname | awk -F: '{print $4}' | tr , '\n'

This has 3 parts:

1 - getent group groupname shows the line of the group in "/etc/group" file. Alternative to cat /etc/group | grep groupname.

2 - awk print's only the members in a single line separeted with ',' .

3 - tr replace's ',' with a new line and print each user in a row.

4 - Optional: You can also use another pipe with sort, if the users are too many.

Regards

Solution 15 - Linux

Here is a script which returns a list of users from /etc/passwd and /etc/group it doesn't check NIS or LDAP, but it does show users who have the group as their default group Tested on Debian 4.7 and solaris 9

#!/bin/bash

MYGROUP="user"

# get the group ID
MYGID=`grep $MYGROUP /etc/group | cut -d ":" -f3`
if [[ $MYGID != "" ]]
then
  # get a newline-separated list of users from /etc/group 
  MYUSERS=`grep $MYGROUP /etc/group | cut -d ":" -f4| tr "," "\n"`
  # add a newline
  MYUSERS=$MYUSERS$'\n'
  # add the users whose default group is MYGROUP from /etc/passwod 
  MYUSERS=$MYUSERS`cat /etc/passwd |grep $MYGID | cut -d ":" -f1`

  #print the result as a newline-separated list with no duplicates (ready to pass into a bash FOR loop)
  printf '%s\n' $MYUSERS  | sort | uniq
fi

or as a one-liner you can cut and paste straight from here (change the group name in the first variable)

MYGROUP="user";MYGID=`grep $MYGROUP /etc/group | cut -d ":" -f3`;printf '%s\n' `grep $MYGROUP /etc/group | cut -d ":" -f4| tr "," "\n"`$'\n'`cat /etc/passwd |grep $MYGID | cut -d ":" -f1`  | sort | uniq

Solution 16 - Linux

In UNIX (as opposed to GNU/Linux), there's the listusers command. See the Solaris man page for listusers.

Note that this command is part of the open-source Heirloom Project. I assume that it's missing from GNU/Linux because RMS doesn't believe in groups and permissions. :-)

Solution 17 - Linux

Here's a very simple awk script that takes into account all common pitfalls listed in the other answers:

getent passwd | awk -F: -v group_name="wheel" '
  BEGIN {
    "getent group " group_name | getline groupline;
    if (!groupline) exit 1;
    split(groupline, groupdef, ":");
    guid = groupdef[3];
    split(groupdef[4], users, ",");
    for (k in users) print users[k]
  }
  $4 == guid {print $1}'

I'm using this with my ldap-enabled setup, runs on anything with standards-compliant getent & awk, including solaris 8+ and hpux.

Solution 18 - Linux

I think the easiest way is the following steps, you won't need to install any package or software:

  1. First, you find out the GID of the group that you want to know the users, there are a lot of ways for that: cat /etc/group (the last column is the GID) id user (the user is someone who belongs to the group)

  2. Now you will list all the user on the file /etc/passwd, but you will apply some filters with the following sequel of commands to get just the members of the previous group.

cut -d: -f1,4 /etc/passwd |grep GID (the GID is the number you got from the step 1)

cut command will select just some "columns" of the file, the parameter d sets the delimiter ":" in this case, the parameter -f selects the "fields" (or columns) to be shown 1 and 4 in out case (on the file /etc/passwd, the 1º column is the name of the user and the 4º is the GID of the group which the user belongs), to finalize the |grep GID will filter just the group (on the 4º column) that you had chosen.

Solution 19 - Linux

Here's another Python one-liner that takes into account the user's default group membership (from /etc/passwd)as well as from the group database (/etc/group)

python -c "import grp,pwd; print set(grp.getgrnam('mysupercoolgroup')[3]).union([u[0] for u in pwd.getpwall() if u.pw_gid == grp.getgrnam('mysupercoolgroup')[2]])"

Solution 20 - Linux

I have tried grep 'sample-group-name' /etc/group,that will list all the member of the group you specified based on the example here

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questionuser323094View Question on Stackoverflow
Solution 1 - LinuxJosh HView Answer on Stackoverflow
Solution 2 - LinuxZedView Answer on Stackoverflow
Solution 3 - LinuxNarayanaperumal GurusamyView Answer on Stackoverflow
Solution 4 - LinuxMemoView Answer on Stackoverflow
Solution 5 - LinuxJose BagatelliView Answer on Stackoverflow
Solution 6 - LinuxDidier TrossetView Answer on Stackoverflow
Solution 7 - LinuxPaweł NadolskiView Answer on Stackoverflow
Solution 8 - LinuxBhavikView Answer on Stackoverflow
Solution 9 - LinuxostiView Answer on Stackoverflow
Solution 10 - LinuxBilly McCloskeyView Answer on Stackoverflow
Solution 11 - LinuxsoinkleinedView Answer on Stackoverflow
Solution 12 - LinuxAndrewView Answer on Stackoverflow
Solution 13 - LinuxparsecpythonView Answer on Stackoverflow
Solution 14 - LinuxioaniatrView Answer on Stackoverflow
Solution 15 - Linuxandrew lorienView Answer on Stackoverflow
Solution 16 - LinuxAlun CarrView Answer on Stackoverflow
Solution 17 - LinuxyunakeView Answer on Stackoverflow
Solution 18 - LinuxMauro MatsudoView Answer on Stackoverflow
Solution 19 - LinuxBrian MintonView Answer on Stackoverflow
Solution 20 - Linuxjameshwart lopezView Answer on Stackoverflow