Comment lister tous les utilisateurs d'un groupe Linux?

Comment lister tous les membres d'un groupe sous Linux (et éventuellement d'autres unices)?

258
demandé sur ekad 2010-05-14 19:28:43

18 réponses

Malheureusement, il n'y a pas de bon moyen portable de le faire que je connaisse. Si vous essayez d'analyser /etc/group, comme d'autres le suggèrent, vous manquerez les utilisateurs qui ont ce groupe comme groupe principal et tous ceux qui ont été ajoutés à ce groupe via un mécanisme autre que les fichiers plats UNIX (par exemple LDAP, nis, pam-pgsql, etc.).

Si je devais absolument le faire moi-même, je le ferais probablement à l'envers: utilisez id pour obtenir les groupes de chaque utilisateur sur le système (ce qui va tirer toutes les sources visible pour NSS), et utilisez Perl ou quelque chose de similaire pour maintenir une table de hachage pour chaque groupe découvert en notant l'appartenance de cet utilisateur.

Edit: bien sûr, cela vous laisse avec un problème similaire: comment obtenir une liste de tous les utilisateurs du système. Étant donné que mon emplacement utilise uniquement des fichiers plats et LDAP, je peux simplement obtenir une liste des deux emplacements, mais cela peut ou non être vrai pour votre environnement.

Edit 2: Quelqu'un, en passant, m'a rappelé que getent passwd retourne une liste de tous les utilisateurs le système, y compris ceux de LDAP/NIS / etc., mais getent group encore manquera toujours les utilisateurs qui sont membres uniquement via l'entrée de groupe par défaut, de sorte que m'a inspiré d'écrire ce hack rapide.


#!/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 (zed@debian.org or zed@resonant.org)
#
# 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";
    }
}
98
répondu Zed 2013-04-12 15:49:07
getent group <groupname>;

Il est portable sur Linux et Solaris, et il fonctionne avec les fichiers de groupe/mot de passe locaux, les configurations NIS et LDAP.

225
répondu Josh H 2014-02-06 20:46:21

Utilisez Python pour lister les membres du Groupe:

Python-c "importer grp; imprimer grp.getgrnam ('GROUP_NAME') [3] "

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

38
répondu Narayanaperumal Gurusamy 2015-08-04 20:14:48
lid -g groupname | cut -f1 -d'(' 
37
répondu Memo 2011-08-15 16:36:03

La commande suivante répertorie tous les utilisateurs appartenant à <your_group_name>, mais uniquement ceux gérés par la base de données /etc/group, pas LDAP, NIS, etc. fonctionne également pour les groupes secondaires uniquement , Il ne listera pas les utilisateurs qui ont ce groupe défini comme primaire puisque le groupe principal est stocké comme GID (ID de groupe numérique) dans le fichier /etc/passwd.

grep <your_group_name> /etc/group
24
répondu J.B 2016-11-10 00:00:41

La commande suivante répertorie tous les utilisateurs appartenant à <your_group_name>, mais uniquement ceux gérés par la base de données /etc/group, pas LDAP, NIS, etc. fonctionne également pour les groupes secondaires uniquement , Il ne listera pas les utilisateurs qui ont ce groupe défini comme primaire puisque le groupe principal est stocké comme GID (ID de groupe numérique) dans le fichier /etc/passwd.

awk -F: '/^groupname/ {print $4;}' /etc/group
15
répondu Didier Trosset 2016-11-10 00:01:54

Le script shell suivant parcourra tous les utilisateurs et n'imprimera que les noms d'utilisateurs appartenant à un groupe donné:

#!/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

Exemple d'Utilisation:

./script 'DOMAIN+Group Name'

Remarque: Cette solution vérifiera NIS et LDAP pour les utilisateurs et les Groupes (pas seulement les fichiers passwd et group). Il prendra également en compte les utilisateurs non ajoutés à un groupe mais ayant un groupe défini comme groupe principal.

Edit: correction ajoutée pour un scénario rare où l'utilisateur n'appartient pas au groupe avec le même nom.

Edit: écrit sous la forme d'un script shell; ajouté true pour quitter avec le statut 0 comme suggéré par @Max Chernyak alias hakunin; mis au rebut stderr afin de sauter ces occasionnels groups: cannot find name for group ID xxxxxx.

10
répondu Paweł Nadolski 2018-04-24 17:36:07

Vous pouvez le faire en une seule ligne de commande:

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

La commande ci-dessus répertorie tous les utilisateurs ayant groupname comme groupe principal

Si vous souhaitez également lister les utilisateurs ayant groupname comme groupe secondaire, utilisez la commande suivante

getent group <groupname> | cut -d: -f4 |  tr ',' '\n'
5
répondu Bhavik 2017-03-07 09:28:03

L'implémentation de Zed devrait probablement être étendue pour fonctionner sur certains des autres grands UNIX.

Quelqu'un a accès au matériel Solaris ou HP-UX?; n'a pas de test de ces cas.

#!/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 (zed@debian.org or zed@resonant.org)
#
# 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";
    }
}

S "il y a une meilleure façon de partager cette suggestion, s" il vous plaît laissez-moi savoir; j "ai examiné plusieurs façons, et c" est ce que je suis venu avec.

3
répondu Billy McCloskey 2013-12-30 23:21:32

Je l'ai fait de la même manière que le code perl ci-dessus, mais j'ai remplacé getent et id par des fonctions Perl natives. Il est beaucoup plus rapide et devrait fonctionner à travers différentes saveurs *nix.

#!/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";
3
répondu soinkleined 2015-07-14 07:21:18

Juste un peu grep et tr:

$ grep ^$GROUP /etc/group | grep -o '[^:]*$' | tr ',' '\n'
user1
user2
user3
2
répondu osti 2010-05-14 15:32:28

Il existe un paquet Debian et Ubuntu très pratique appelé 'members ' qui fournit cette fonctionnalité:

Description: Affiche les membres d'un groupe; par défaut, tous les membres members est le complément des groupes: alors que groups affiche les groupes auxquels appartient un utilisateur spécifié, members affiche les utilisateurs appartenant à un groupe spécifié.

... Vous pouvez demander des membres primaires, des membres secondaires, à la fois sur une ligne, chacune sur des lignes séparées.

2
répondu Andrew 2015-06-29 08:56:33

Voici un script qui renvoie une liste d'utilisateurs de/etc / passwd et/etc / group il ne vérifie pas NIS ou LDAP, mais il affiche les utilisateurs qui ont le groupe comme groupe par défaut Testé sur Debian 4.7 et 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

Ou comme un one-liner, vous pouvez couper et coller directement à partir d'ici (changer le nom du groupe dans la première 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
0
répondu andrew lorien 2013-12-16 02:07:48

Dans UNIX (par opposition à GNU / Linux), il y a la commande listusers. Voir la page de manuel Solaris pour listusers.

Notez que cette commande fait partie du projet open-source Heirloom. Je suppose qu'il manque de GNU / Linux parce que RMS ne croit pas aux groupes et aux autorisations. :-)

0
répondu Alun Carr 2015-11-10 21:33:09

Voici un script awk très simple qui prend en compte tous les pièges courants listés dans les autres réponses:

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}'

Je l'utilise avec ma configuration compatible ldap, fonctionne sur tout ce qui est conforme aux normes getent & awk, y compris solaris 8+ et hpux.

0
répondu yunake 2016-01-16 23:30:03
getent group insert_group_name_here | awk -F ':' '{print $4}' | sed 's|,| |g'

Cela renvoie une liste d'utilisateurs séparés par un espace que j'ai utilisée dans les scripts pour remplir les tableaux.

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

Ou

userarray+=("$(getent group GROUPNAME | awk -F ':' '{print $4}' | sed 's|,| |g')")
0
répondu spezticle 2016-07-20 15:37:23
getent group groupname | awk -F: '{print $4}' | tr , '\n'

Cela a 3 parties:

1 - getent group groupname affiche la ligne du groupe dans le fichier "/ etc / group". Alternative à cat /etc/group | grep groupname.

2 - awk imprimer est seulement les membres dans une seule ligne séparée avec','.

3 - tr remplacez', ' par une nouvelle ligne et imprimez chaque utilisateur dans une rangée.

4 - Facultatif: Vous pouvez également utiliser un autre tuyau avec sort, si les utilisateurs sont trop nombreux.

Cordialement

0
répondu ioaniatr 2017-02-25 18:08:43

J'ai essayé grep 'sample-group-name' /etc/group,qui liste tous les membres du groupe que vous avez spécifié à l'exemple ici

-1
répondu jameshwart lopez 2016-02-11 02:59:20