Wie liste ich alle Benutzer in einer Linux-Gruppe auf?


273

Wie liste ich alle Mitglieder einer Gruppe unter Linux (und möglicherweise anderen Unices) auf?


1
@ Silmari89, Nicht wenn er es programmatisch machen will.
Paul Tomblin

2
Ich bin neu hier und habe herausgefunden, dass SF direkt nach dem Posten der Frage existiert. Ich bin damit einverstanden, dass es entweder zu SF oder SO gehört.
user323094

5
Heh, jetzt hat es natürlich eine programmatische Lösung, also könnte es auch hier gerechtfertigt sein.
Zed

Antworten:


103

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, idum 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 passwdeine 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";
    }
}

3
Vielen Dank an alle, die geantwortet haben. Ich suchte nach einem tragbaren Weg, dies zu tun. Ihre Information, dass es keinen einfachen und tragbaren Weg gibt, war hilfreich. Sie haben auch die Umstände am ausführlichsten beschrieben, die mir geholfen haben, das Problem besser zu verstehen. Ich weiß das zu schätzen und habe Ihre Antwort als die akzeptierte gewählt.
user323094

2
Wäre es Ihnen möglich, Ihr Skript an die Linux Foundation zu spenden? Es ist 2012 und es gibt immer noch keine einfache Möglichkeit, Mitglieder einer Gruppe zu finden. Das ist das, was mich an Linux frustriert.
Winteck

6
Ich habe eine ISC-ähnliche Lizenz für Sie hinzugefügt, die mit nahezu jeder Gruppe kompatibel sein sollte. Sie können es jederzeit dort einreichen, wo Sie glauben, dass es akzeptiert wird.
Zed

PAM liefert keine Kontoinformationen. Es ist der Name Service Switch (nsswitch), der das macht. Nicht alle 'Datenbanken' (Datenanbieter) unterstützen die Aufzählung und getent passwdfunktionieren daher möglicherweise nicht (wenn Sie beispielsweise sssd verwenden).

Gültiger Punkt zu PAM vs NSS - Ich habe die Referenz geändert. Obwohl ich es nicht verwendet habe, sieht sssd auf den ersten Blick eher wie ein nscd-Ersatz aus als wie ein richtiger Datenprovider, und wenn es kaputt geht, getent passwdwürde ich das als Fehler in sssd betrachten.
Zed

239
getent group <groupname>;

Es ist sowohl unter Linux als auch unter Solaris portierbar und funktioniert mit lokalen Gruppen- / Kennwortdateien, NIS- und LDAP-Konfigurationen.


43
Zeigt keine Benutzer an, deren Gruppe die Standardgruppe ist.
rlpowell


39
lid -g groupname | cut -f1 -d'(' 

7
Dies wäre der schönste Weg, außer dass sich der Deckel nicht in einer Standard-Debian-Installation befindet. In Ubuntu befindet es sich im optionalen Paket libuser (nicht in id-utils mit demselben Namen). Ich habe es nicht in Debian gefunden :(
user323094

Arbeitete für mich unter Scientific Linux
blong

auf Debian Wheezy ist Deckel auch auf libuser Paket
Lluís

2
@ JohnMcGehee RHEL sollte AustereLinux
goelakash

1
'-g' ist für mich keine Option. Ich habe id-utils Version 4.6 unter Ubuntu 16.04 installiert.
Wilson Biggs

25

Der folgende Befehl listet alle Benutzer auf <your_group_name>, die zu gehören , aber nur diejenigen, die von der /etc/groupDatenbank 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

4
Sie können direkt zu dieser Datei greifen, z. B. grep <Benutzername> / etc / group. Schneller und weniger Aufwand.
Paintbox

16

Der folgende Befehl listet alle Benutzer auf <your_group_name>, die zu gehören , aber nur diejenigen, die von der /etc/groupDatenbank 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

7
Zeigt keine Benutzer an, deren Gruppe die Standardgruppe ist.
rlpowell

3
Überprüft nicht NIS und LDAP.
Paweł Nadolski

12

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 passwdund groupDateien). 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 0Status zu beenden, wie von @Max Chernyak aka hakunin vorgeschlagen ; verworfen stderr, um diese gelegentlich zu überspringen groups: cannot find name for group ID xxxxxx.


Das ist großartig und sehr prägnant, aber es druckt den Gruppennamen sowie die Benutzernamen
Andrew Lorien

@andrewlorien, ich hoffe, ich habe das von Ihnen erwähnte Problem behoben. Wenn nicht, geben Sie bitte weitere Details an.
Paweł Nadolski

Dieses Snippet ist gut, gibt aber den Exit-Code 1 zurück. Gibt es einen Grund, warum es nicht 0 zurückgibt? Einfache Lösung vielleicht?
Max Chernyak

@hakunin, es gibt keine 0 zurück, wenn der Nachname nicht zur Gruppe gehört. Sie können "|| true" an die Endanweisung anhängen, um immer 0 zu erhalten, wenn Sie dies wünschen. Sie können dann die Ausgabe überprüfen, um festzustellen, ob ein Benutzer gefunden wurde.
Paweł Nadolski

@ PawełNadolski Mir wurde klar, also fügte ich hinzu ; true. Die Rückgabe von 0 ist gut, um ein Auslösen Ihres Konfigurationsmanagementsystems (Chef, Ansible usw.) zu vermeiden.
Max Chernyak

7

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'

1
Vorsichtsmaßnahme: grepEntspricht einem Benutzer, dessen Name die Gruppennummer enthält (z. B. sc0ttwird er als Teil der rootGruppe 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.)
Scott Stevens

@ScottS Ein echter Boxensturz. Würde Schritte empfehlen empfehlen
Bhavik

3

nur ein wenig grep und tr:

$ grep ^$GROUP /etc/group | grep -o '[^:]*$' | tr ',' '\n'
user1
user2
user3

4
Zeigt keine Benutzer an, deren Gruppe die Standardgruppe ist.
rlpowell

3

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.


Bestätigt die Arbeit unter Solaris 10 nach dem Wechsel id -Gnzu/usr/xpg4/bin/id -G -n
user667489

3

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";

Eine Antwort nur mit einem Link ist keine gute Antwort auf den Stapelüberlauf. Bitte erwägen Sie, dies zu löschen, da dies keine Antwort auf die Frage liefert oder näher darauf eingeht, wie diese Antwort besser ist als die akzeptierte Antwort. Oder Sie können dies als Kommentar hinzufügen, sobald Sie genügend Ruf haben. Sie können jederzeit Ihre eigenen Beiträge kommentieren.
Dipen Shah

2

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.


Was ist, wenn die Operation openwrt verwendet?
user2284570

Praktisch zwar, meldet aber leider keine Domaingruppenmitglieder.
Simlev

1
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')")

0

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

0

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. :-)


1
Während dieser Link die Frage beantworten kann, ist es besser, die wesentlichen Teile der Antwort hier aufzunehmen und den Link als Referenz bereitzustellen. Nur-Link-Antworten können ungültig werden, wenn sich die verknüpfte Seite ändert. - Von der Überprüfung
Knuhol

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.
Alun Carr

Von der Heirloom Project-Website: Das Heirloom Project bietet traditionelle Implementierungen von Standard-Unix-Dienstprogrammen. In vielen Fällen wurden sie aus originalem Unix-Material abgeleitet, das von Caldera und Sun als Open Source veröffentlicht wurde. Schnittstellen folgen der traditionellen Praxis; Sie bleiben im Allgemeinen mit System V kompatibel, obwohl manchmal Erweiterungen bereitgestellt werden, die im Laufe der Zeit allgemein verwendet wurden. Die meisten Dienstprogramme sind auch in einer Variante enthalten, die auf POSIX-Konformität abzielt.
Alun Carr

0

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.


0
getent group groupname | awk -F: '{print $4}' | tr , '\n'

Dies hat 3 Teile:

1 - getent group groupnamezeigt die Zeile der Gruppe in der Datei "/ etc / group". Alternative zu cat /etc/group | grep groupname.

2 - awkDrucken Sie nur die Elemente in einer einzelnen Zeile, die durch ',' getrennt ist.

3 - trErsetzen 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


0

Ich denke, der einfachste Weg sind die folgenden Schritte: Sie müssen kein Paket oder keine Software installieren:

  1. 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)

  2. 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.


0

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]])"

-1

Ich habe versucht grep 'sample-group-name' /etc/group, das alle Mitglieder der Gruppe aufzulisten, die Sie anhand des Beispiels hier angegeben haben


1
Grepping /etc/groupist 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.
David Ferenczy Rogožan
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.