Comment répertorier tous les membres d'un groupe sous Linux (et éventuellement d'autres unités)?
Comment répertorier tous les membres d'un groupe sous Linux (et éventuellement d'autres unités)?
Réponses:
Malheureusement, il n'y a aucun bon moyen portable de faire cela que je sache. 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 toute personne qui a été ajoutée à ce groupe via un mécanisme autre que les fichiers plats UNIX (c'est-à-dire 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 tirera toutes les sources visibles pour NSS), et utilisez Perl ou quelque chose de similaire pour maintenir un hachage table 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 chaque utilisateur sur le 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é qu'il getent passwd
retournerait une liste de tous les utilisateurs du système, y compris ceux de LDAP / NIS / etc., mais getent group
qu'il manquerait toujours les utilisateurs qui sont membres uniquement via l'entrée de groupe par défaut, ce qui m'a inspiré écrivez 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 passwd
peuvent donc ne pas fonctionner (si, par exemple, vous utilisez sssd).
getent passwd
je considérerais qu'il s'agit d'un bogue dans sssd.
Utilisez Python pour répertorier les membres du groupe:
python -c "import grp; print grp.getgrnam ('GROUP_NAME') [3]"
lid -g groupname | cut -f1 -d'('
La commande suivante liste tous les utilisateurs appartenant <your_group_name>
, mais seulement celles qui sont gérées par la /etc/group
base de données, pas LDAP, NIS, etc. Il a également travaille pour des groupes secondaires seulement , il ne sera pas les utilisateurs de la liste qui ont cet ensemble du groupe comme principal puisque le groupe primaire est stocké sous GID
(ID de groupe numérique) dans le fichier /etc/passwd
.
grep <your_group_name> /etc/group
La commande suivante liste tous les utilisateurs appartenant <your_group_name>
, mais seulement celles qui sont gérées par la /etc/group
base de données, pas LDAP, NIS, etc. Il a également travaille pour des groupes secondaires seulement , il ne sera pas les utilisateurs de la liste qui ont cet ensemble du groupe comme principal puisque le groupe primaire est stocké sous 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'utilisateur qui appartiennent à 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 passwd
et les group
fichiers). Il prendra également en compte les utilisateurs non ajoutés à un groupe mais dont le groupe est défini comme groupe principal.
Modifier: correction d'un scénario rare dans lequel l'utilisateur n'appartient pas à un groupe du même nom.
Edit: écrit sous la forme d'un script shell; ajouté true
pour quitter avec le 0
statut suggéré par @Max Chernyak aka hakunin ; jetés stderr
afin de sauter ceux qui sont occasionnels groups: cannot find name for group ID xxxxxx
.
; true
. Renvoyer 0 est bon pour éviter de déclencher votre système de gestion de configuration (Chef, Ansible, etc.).
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 dont le nom de groupe est leur groupe principal
Si vous souhaitez également répertorier les utilisateurs dont le nom de groupe est leur groupe secondaire, utilisez la commande suivante
getent group <groupname> | cut -d: -f4 | tr ',' '\n'
grep
correspondra à un utilisateur dont le nom contient le numéro de groupe (par exemple, sc0tt
sera affiché comme faisant partie du root
groupe). Si c'est un problème, utilisez l'expression régulière :$(getent group <groupname> | cut -d: -f3)\$
(correspond au point-virgule, à l'ID de groupe et à la fin de la ligne). (N'ajoutez pas de guillemets au regex, ou bash se plaint.)
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 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 (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 existe une meilleure façon de partager cette suggestion, faites-le moi savoir; J'ai envisagé plusieurs façons, et c'est ce que j'ai trouvé.
id -Gn
à/usr/xpg4/bin/id -G -n
J'ai fait cela 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 avec 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";
Il existe un paquet Debian et Ubuntu pratique appelé « membres » qui fournit cette fonctionnalité:
Description: affiche les membres d'un groupe; par défaut, tous les membres membres sont le complément des groupes: alors que groupes affiche les groupes auxquels appartient un utilisateur spécifié, membres montre les utilisateurs appartenant à un groupe spécifié.
... Vous pouvez demander des membres principaux, des membres secondaires, sur une même ligne, chacun sur des lignes distinctes.
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 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')")
Voici un script qui retourne une liste d'utilisateurs de / etc / passwd et / etc / group qu'il ne vérifie pas NIS ou LDAP, mais il montre 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 en 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
Sous UNIX (par opposition à GNU / Linux), il y a la commande listusers. Consultez la page de manuel Solaris pour les utilisateurs .
Notez que cette commande fait partie du projet Heirloom open-source . Je suppose qu'il est absent de GNU / Linux car RMS ne croit pas aux groupes et aux autorisations. :-)
NAME listusers - print a list of user logins SYNOPSIS listusers [-g groups] [-l logins] DESCRIPTION Listusers prints the name and the gecos information of all users known to the system, sorted by username. Valid options are: -g groups Only print the names of users that belong to the given group. Multiple groups are accepted if separated by commas. -l logins Print only user names that match logins. Multiple user names are accepted if separated by commas.
Voici un script awk très simple qui prend en compte tous les pièges courants répertorié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 sur n'importe quoi avec getent & awk conforme aux normes, y compris Solaris 8+ et hpux.
getent group groupname | awk -F: '{print $4}' | tr , '\n'
Cela comprend 3 parties:
1 - getent group groupname
montre la ligne du groupe dans le fichier "/ etc / group". Alternative à cat /etc/group | grep groupname
.
2 - awk
affiche uniquement les membres sur une seule ligne séparée par ','.
3 - tr
remplacez le ',' par une nouvelle ligne et imprimez chaque utilisateur d'affilée.
4 - Facultatif: vous pouvez également utiliser un autre tuyau avec sort
, si les utilisateurs sont trop nombreux.
Cordialement
Je pense que le moyen le plus simple est les étapes suivantes, vous n'aurez pas besoin d'installer de package ou de logiciel:
Tout d'abord, vous découvrez le GID du groupe dont vous souhaitez connaître les utilisateurs, il existe de nombreuses façons pour cela: cat / etc / group (la dernière colonne est le GID) id user (l'utilisateur est quelqu'un qui appartient à le groupe)
Vous allez maintenant lister tous les utilisateurs sur le fichier / etc / passwd, mais vous appliquerez quelques 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électionnera 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 (sur 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 juste le groupe (sur la colonne 4º) que vous avait choisi.
Voici un autre one-liner Python qui prend en compte l'appartenance au groupe par défaut de l'utilisateur (de /etc/passwd
) ainsi que de la base de données de groupe ( /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]])"
J'ai essayé grep 'sample-group-name' /etc/group
, cela listera tous les membres du groupe que vous avez spécifié sur la base de l'exemple ici
/etc/group
est déjà dans au moins 3 autres réponses, quelle valeur votre réponse leur ajoute-t-elle? En outre, toutes ces autres réponses indiquent que cette solution ne fonctionne que pour les groupes secondaires et ne fonctionne pas non plus pour les comptes gérés par LDAP, NIS, etc.