Wie liste ich alle Mitglieder einer Gruppe unter Linux (und möglicherweise anderen Unices) auf?
Wie liste ich alle Mitglieder einer Gruppe unter Linux (und möglicherweise anderen Unices) auf?
Antworten:
Leider gibt es keinen guten, tragbaren Weg, dies zu tun, den ich kenne. Wenn Sie versuchen, / etc / group zu analysieren, wie andere vorschlagen, werden Sie Benutzer vermissen, die diese Gruppe als primäre Gruppe haben, und alle, die dieser Gruppe über einen anderen Mechanismus als UNIX-Flatfiles hinzugefügt wurden (z. B. LDAP, NIS, pam-pgsql usw.).
Wenn ich dies unbedingt selbst tun müsste, würde ich es wahrscheinlich umgekehrt tun: Verwenden Sie diese Option, id
um die Gruppen aller Benutzer auf dem System abzurufen (wodurch alle für NSS sichtbaren Quellen abgerufen werden), und verwenden Sie Perl oder ähnliches, um einen Hash zu verwalten Tabelle für jede entdeckte Gruppe unter Angabe der Mitgliedschaft dieses Benutzers.
Bearbeiten: Natürlich haben Sie ein ähnliches Problem: Wie Sie eine Liste aller Benutzer im System erhalten. Da mein Standort nur Flatfiles und LDAP verwendet, kann ich nur eine Liste von beiden Standorten abrufen. Dies kann jedoch für Ihre Umgebung zutreffen oder nicht.
Bearbeiten 2: Jemand hat mich im Vorbeigehen daran erinnert, dass getent passwd
eine Liste aller Benutzer im System zurückgegeben wird, einschließlich derer aus LDAP / NIS / etc., Aber getent group
immer noch Benutzer vermisst werden, die nur über den Standardgruppeneintrag Mitglieder sind, was mich dazu inspiriert hat schreibe diesen schnellen 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 (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
funktionieren daher möglicherweise nicht (wenn Sie beispielsweise sssd verwenden).
getent passwd
würde ich das als Fehler in sssd betrachten.
Verwenden Sie Python, um Gruppenmitglieder aufzulisten:
python -c "import grp; print grp.getgrnam ('GROUP_NAME') [3]"
lid -g groupname | cut -f1 -d'('
Der folgende Befehl listet alle Benutzer auf <your_group_name>
, die zu gehören , aber nur diejenigen, die von der /etc/group
Datenbank verwaltet werden , nicht LDAP, NIS usw. Er funktioniert auch nur für sekundäre Gruppen . Er listet keine Benutzer auf, für die diese Gruppe als primär festgelegt wurde, da die primäre Gruppe ist gespeichert als GID
(numerische Gruppen-ID) in der Datei /etc/passwd
.
grep <your_group_name> /etc/group
Der folgende Befehl listet alle Benutzer auf <your_group_name>
, die zu gehören , aber nur diejenigen, die von der /etc/group
Datenbank verwaltet werden , nicht LDAP, NIS usw. Er funktioniert auch nur für sekundäre Gruppen . Er listet keine Benutzer auf, für die diese Gruppe als primär festgelegt wurde, da die primäre Gruppe ist gespeichert als GID
(numerische Gruppen-ID) in der Datei /etc/passwd
.
awk -F: '/^groupname/ {print $4;}' /etc/group
Das folgende Shell-Skript durchläuft alle Benutzer und druckt nur die Benutzernamen, die zu einer bestimmten Gruppe gehören:
#!/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
Anwendungsbeispiel:
./script 'DOMAIN+Group Name'
Hinweis: Diese Lösung überprüft NIS und LDAP auf Benutzer und Gruppen (nicht nur passwd
und group
Dateien). Dabei werden auch Benutzer berücksichtigt, die keiner Gruppe hinzugefügt wurden, deren Gruppe jedoch als primäre Gruppe festgelegt ist.
Bearbeiten: Korrektur für seltenes Szenario hinzugefügt, in dem Benutzer nicht zu einer Gruppe mit demselben Namen gehören.
Bearbeiten: in Form eines Shell-Skripts geschrieben; hinzugefügt true
, um mit dem 0
Status zu beenden, wie von @Max Chernyak aka hakunin vorgeschlagen ; verworfen stderr
, um diese gelegentlich zu überspringen groups: cannot find name for group ID xxxxxx
.
; true
. Die Rückgabe von 0 ist gut, um ein Auslösen Ihres Konfigurationsmanagementsystems (Chef, Ansible usw.) zu vermeiden.
Sie können dies in einer einzigen Befehlszeile tun:
cut -d: -f1,4 /etc/passwd | grep $(getent group <groupname> | cut -d: -f3) | cut -d: -f1
Der obige Befehl listet alle Benutzer auf, deren primäre Gruppe der Gruppenname ist
Wenn Sie auch die Benutzer mit dem Gruppennamen als sekundäre Gruppe auflisten möchten , verwenden Sie den folgenden Befehl
getent group <groupname> | cut -d: -f4 | tr ',' '\n'
grep
Entspricht einem Benutzer, dessen Name die Gruppennummer enthält (z. B. sc0tt
wird er als Teil der root
Gruppe angezeigt ). Wenn dies ein Problem ist, verwenden Sie den regulären Ausdruck :$(getent group <groupname> | cut -d: -f3)\$
(entspricht dem Semikolon, der Gruppen-ID und dem Zeilenende). (Fügen Sie dem regulären Ausdruck keine Anführungszeichen hinzu oder beschweren Sie sich.)
Die Implementierung von Zed sollte wahrscheinlich erweitert werden, um auf einigen der anderen wichtigen UNIX-Programme zu funktionieren.
Hat jemand Zugriff auf Solaris oder HP-UX-Hardware?; habe diese Fälle nicht getestet.
#!/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";
}
}
Wenn es einen besseren Weg gibt, diesen Vorschlag zu teilen, lassen Sie es mich bitte wissen. Ich habe viele Möglichkeiten in Betracht gezogen, und das habe ich mir ausgedacht.
id -Gn
zu/usr/xpg4/bin/id -G -n
Ich habe dies ähnlich wie im obigen Perl-Code gemacht, aber getent und id durch native Perl-Funktionen ersetzt. Es ist viel schneller und sollte über verschiedene * nix-Geschmacksrichtungen hinweg funktionieren.
#!/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";
Es gibt ein praktisches Debian- und Ubuntu-Paket namens " Mitglieder ", das diese Funktionalität bietet:
Beschreibung: Zeigt die Mitglieder einer Gruppe an. Standardmäßig sind alle Mitglieder Mitglieder das Komplement von Gruppen: Während Gruppen die Gruppen anzeigen, zu denen ein bestimmter Benutzer gehört, zeigen Mitglieder Benutzer an, die zu einer bestimmten Gruppe gehören.
... Sie können nach primären Mitgliedern und sekundären Mitgliedern fragen, beide in einer Zeile, jeweils in separaten Zeilen.
getent group insert_group_name_here | awk -F ':' '{print $4}' | sed 's|,| |g'
Dies gibt eine durch Leerzeichen getrennte Liste von Benutzern zurück, die ich in Skripten zum Auffüllen von Arrays verwendet habe.
for i in $(getent group ftp | awk -F ':' '{print $4}' | sed 's|,| |g')
do
userarray+=("$i")
done
oder
userarray+=("$(getent group GROUPNAME | awk -F ':' '{print $4}' | sed 's|,| |g')")
Hier ist ein Skript, das eine Liste von Benutzern aus / etc / passwd und / etc / group zurückgibt. Es überprüft weder NIS noch LDAP, zeigt jedoch Benutzer an, deren Gruppe die Standardgruppe ist, die unter Debian 4.7 und Solaris 9 getestet wurde
#!/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
oder als Einzeiler können Sie direkt von hier aus ausschneiden und einfügen (ändern Sie den Gruppennamen in der ersten Variablen)
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
Unter UNIX (im Gegensatz zu GNU / Linux) gibt es den Befehl listusers. Listenbenutzer finden Sie auf der Solaris-Manpage .
Beachten Sie, dass dieser Befehl Teil des Open-Source- Heirloom-Projekts ist . Ich gehe davon aus, dass es in GNU / Linux fehlt, weil RMS nicht an Gruppen und Berechtigungen glaubt. :-)
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.
Hier ist ein sehr einfaches awk-Skript, das alle in den anderen Antworten aufgeführten Fallstricke berücksichtigt:
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}'
Ich verwende dies mit meinem ldap-fähigen Setup, läuft auf allem mit standardkonformem getent & awk, einschließlich Solaris 8+ und hpux.
getent group groupname | awk -F: '{print $4}' | tr , '\n'
Dies hat 3 Teile:
1 - getent group groupname
zeigt die Zeile der Gruppe in der Datei "/ etc / group". Alternative zu cat /etc/group | grep groupname
.
2 - awk
Drucken Sie nur die Elemente in einer einzelnen Zeile, die durch ',' getrennt ist.
3 - tr
Ersetzen Sie ',' durch eine neue Zeile und drucken Sie jeden Benutzer in einer Reihe.
4 - Optional: Sie können auch eine andere Pipe verwenden sort
, wenn zu viele Benutzer vorhanden sind.
Grüße
Ich denke, der einfachste Weg sind die folgenden Schritte: Sie müssen kein Paket oder keine Software installieren:
Zuerst finden Sie die GID der Gruppe heraus, die Sie den Benutzern mitteilen möchten. Dafür gibt es viele Möglichkeiten: cat / etc / group (die letzte Spalte ist die GID) id user (der Benutzer ist jemand, zu dem er gehört die Gruppe)
Jetzt werden Sie alle Benutzer in der Datei / etc / passwd auflisten, aber Sie werden einige Filter mit der folgenden Folge von Befehlen anwenden, um nur die Mitglieder der vorherigen Gruppe zu erhalten.
cut -d: -f1,4 / etc / passwd | grep GID (die GID ist die Nummer, die Sie aus Schritt 1 erhalten haben)
Der Befehl cut wählt nur einige "Spalten" der Datei aus, der Parameter d setzt das Trennzeichen ":" In diesem Fall wählt der Parameter -f die "Felder" (oder Spalten) aus, die in unserem Fall 1 und 4 angezeigt werden sollen In der Datei / etc / passwd ist die 1º-Spalte der Name des Benutzers und die 4º-Spalte die GID der Gruppe, zu der der Benutzer gehört. Um die | grep-GID abzuschließen, wird nur die Gruppe (in der 4º-Spalte) gefiltert, die Sie verwenden hatte ausgewählt.
Hier ist ein anderer Python Einzeiler , die berücksichtigt , den Standard - Gruppenmitgliedschaft des Benutzers (von /etc/passwd
) sowie aus der Gruppe Datenbank ( /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]])"
Ich habe versucht grep 'sample-group-name' /etc/group
, das alle Mitglieder der Gruppe aufzulisten, die Sie anhand des Beispiels hier angegeben haben
/etc/group
ist bereits in mindestens 3 anderen Antworten enthalten. Welchen Wert hat Ihre Antwort für sie? Alle diese anderen Antworten haben auch Kommentare, dass eine solche Lösung nur für sekundäre Gruppen funktioniert und auch nicht für Konten, die von LDAP, NIS usw. verwaltet werden.