web-dev-qa-db-fra.com

Comment lister tous les utilisateurs d'un groupe Linux?

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

269
user323094

Malheureusement, il n'y a pas de bonne façon portable de le faire que je sache. Si vous essayez d’analyser/etc/group, comme le suggèrent d’autres personnes, vous allez rater les utilisateurs qui ont ce groupe comme groupe principal et toute personne qui a été ajoutée à ce groupe via un mécanisme autre que les fichiers plats UNIX (comme LDAP, NIS, etc.). pam-pgsql, etc.).

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

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

Edit 2: Quelqu'un au passage m'a rappelé que getent passwd renverra une liste de tous les utilisateurs du système, y compris ceux de LDAP/NIS/etc., maisgetent group sera toujours manquer les utilisateurs qui ne sont membres que via l'entrée de groupe par défaut, donc cela m'a inspiré pour é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 ([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";
    }
}
101
Zed
getent group <groupname>;

Il est portable sous Linux et Solaris et fonctionne avec les fichiers de groupes/mots de passe locaux, les configurations NIS et LDAP.

235
Josh H
lid -g groupname | cut -f1 -d'(' 
39
Memo

Utilisez Python pour répertorier les membres du groupe:

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

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

39

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. Elle fonctionne également uniquement pour les groupes secondaires. , il ne répertoriera pas les utilisateurs pour lesquels ce groupe est défini en tant que principal, car le groupe principal est stocké sous le nom GID (ID de groupe numérique) dans le fichier /etc/passwd.

grep <your_group_name> /etc/group
25
J.B

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. Elle fonctionne également uniquement pour les groupes secondaires. , il ne répertoriera pas les utilisateurs pour lesquels ce groupe est défini en tant que principal, car le groupe principal est stocké sous le nom GID (ID de groupe numérique) dans le fichier /etc/passwd.

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

Le script de shell suivant parcourt tous les utilisateurs et n'imprime que les noms d'utilisateur 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érifie les fichiers NIS et LDAP pour les utilisateurs et les groupes (pas uniquement les fichiers passwd et group.). Il prendra également en compte les utilisateurs non ajoutés à un groupe mais dont le groupe est défini comme groupe principal.

Edit: Correctif ajouté pour les scénarios rares dans lesquels l’utilisateur n’appartient pas à un groupe portant le même nom.

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

12
Paweł Nadolski

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 nom de groupe comme leur groupe principal

Si vous souhaitez également répertorier les utilisateurs ayant nom de groupe en tant que groupe secondaire, utilisez la commande suivante

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

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

Quelqu'un a accès au matériel Solaris ou HP-UX? n'a pas testé 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 ([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";
    }
}

S'il existe un meilleur moyen de partager cette suggestion, veuillez me le faire savoir; J'ai envisagé de nombreuses manières et c'est ce que j'ai proposé.

3
Billy McCloskey

J'ai fait ceci similaire au code Perl ci-dessus, mais j'ai remplacé getent et id par des fonctions natives Perl. Il est beaucoup plus rapide et devrait fonctionner avec différents types de * 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
soinkleined

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

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

... Vous pouvez demander des membres principaux, des membres secondaires, tous deux sur une ligne, chacun sur des lignes séparées.

2
Andrew

juste un peu grep et tr:

$ grep ^$GROUP /etc/group | grep -o '[^:]*$' | tr ',' '\n'
user1
user2
user3
2
osti
getent group insert_group_name_here | awk -F ':' '{print $4}' | sed 's|,| |g'

Cela renvoie une liste d'utilisateurs séparés par des espaces que j'ai utilisés dans des scripts pour remplir des 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')")
1
spezticle

Sous UNIX (par opposition à GNU/Linux), vous avez la commande listusers. Voir le page de manuel Solaris pour les utilisateurs de la liste .

Notez que cette commande fait partie de l'open source Heirloom Project . Je suppose que cela ne figure pas dans GNU/Linux car RMS ne croit pas aux groupes et aux autorisations. :-)

0
Alun Carr
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 affiche uniquement les membres d'une seule ligne séparés par ','.

3 - tr remplacez ',' par une nouvelle ligne et imprimez chaque utilisateur l'un après l'autre.

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

Cordialement

0
ioaniatr

Voici un script qui renvoie la liste des utilisateurs de/etc/passwd et de/etc/group. Il ne vérifie pas NIS ou LDAP, mais affiche les utilisateurs ayant 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 une ligne, vous pouvez couper et coller directement à partir d'ici (changez 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
andrew lorien

Voici un script awk très simple qui prend en compte tous les pièges courants énuméré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}'

J'utilise cela avec ma configuration compatible LDAP, fonctionne avec tout ce qui est compatible avec les normes getent & awk, y compris Solaris 8+ et hpux.

0
yunake

Je pense que le moyen le plus simple est les étapes suivantes, vous n’aurez besoin d’installer aucun paquet ou logiciel:

  1. Tout d’abord, vous découvrez le GID du groupe que vous voulez connaître, vous pouvez le faire de différentes manières: cat/etc/group (la dernière colonne est le GID) id utilisateur (l'utilisateur est une personne appartenant au groupe)

  2. Vous allez maintenant lister tous les utilisateurs dans le fichier/etc/passwd, mais vous appliquerez des filtres avec la suite de commandes suivante pour obtenir uniquement les membres du groupe précédent.

cut -d: -f1,4/etc/passwd | grep GID (le GID est le numéro obtenu à l'étape 1)

la commande cut sélectionne seulement quelques "colonnes" du fichier, le paramètre d définit le délimiteur ":" dans ce cas, le paramètre -f sélectionne les "champs" (ou colonnes) à afficher 1 et 4 dans le cas le fichier/etc/passwd, la colonne 1º est le nom de l'utilisateur et le 4º est le GID du groupe auquel l'utilisateur appartient), pour finaliser le | GREP GID filtrera uniquement le groupe (sur la colonne 4º) que avait choisi.

0
Mauro Matsudo