Comment lister tous les utilisateurs d'un groupe Linux?
Comment lister tous les membres d'un groupe sous Linux (et éventuellement d'autres unices)?
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";
}
}
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.
Utilisez Python pour lister les membres du Groupe:
Python-c "importer grp; imprimer grp.getgrnam ('GROUP_NAME') [3] "
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
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
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
.
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'
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.
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";
Juste un peu grep et tr:
$ grep ^$GROUP /etc/group | grep -o '[^:]*$' | tr ',' '\n'
user1
user2
user3
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.
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
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. :-)
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.
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')")
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
J'ai essayé grep 'sample-group-name' /etc/group
,qui liste tous les membres du groupe que vous avez spécifié à l'exemple ici