Alle Mitglieder einer Gruppe auflisten (Mac OS X)

56

Ich habe es mit Googeln versucht, komme aber nicht weiter. Wie kann ich alle Mitglieder einer Gruppe auflisten, die mygroupüber die Befehlszeile in OS X aufgerufen wurde ?

$ dscl . list /groupsholt mir alle Gruppen ... aber wie kann ich die Mitglieder jeder Gruppe sehen?

Meltemi
quelle

Antworten:

40

Sie können verwenden:

dscacheutil -q group -a name admin

oder:

dscacheutil -q group -a name staff

usw.

duperuser
quelle
Das ist meine Lieblingsmethode. Leicht und genau. Vielen Dank!
TryTryAgain
Dies ist eine großartige Antwort, da 90% der Anwendungsfälle damit gelöst werden können und nicht mit den aufwändigeren Skripten, die als Antworten veröffentlicht wurden.
JakeGould
Fügen Sie dies einfach als Alias ​​in Ihre Shell-Startdatei ein, und Sie können einen Ein-Wort-Befehl plus Gruppenname eingeben.
Neil Monroe
Als ich "dscacheutil -q group" ausprobierte, bekam ich 2 Absätze für die Gruppe "admin". Die beiden haben denselben Namen, gid, aber unterschiedliche Benutzerlisten. Irgendeine Idee? Vielen Dank!
Golden Thumb
Nicht unbedingt vollständig. dscacheutil -q group -a name admingab mir nur 1 Ergebnis, während das Shell-Skript des akzeptierten Antworters mir 2 Ergebnisse lieferte.
wisbucky
64

Es gibt keinen Standardbefehl, der alle Mitglieder einer Gruppe in OS X auflistet. Hier ist eine Shell-Funktion, die das macht:

members () { dscl . -list /Users | while read user; do printf "$user "; dsmemberutil checkmembership -U "$user" -G "$*"; done | grep "is a member" | cut -d " " -f 1; }; 

Kopieren Sie die obige Befehlszeile in das Terminal, und geben Sie Folgendes ein (wobei mygroup der Name einer vorhandenen Gruppe ist).members mygroup


Einige Erklärungen für diejenigen, die interessiert sind:

Es gibt fünf verschiedene Möglichkeiten (von denen ich weiß), wie ein Benutzer Mitglied einer Gruppe in OS X werden kann. Es ist nicht garantiert, dass der Befehl alle oder sogar alle Mitglieder meiner Gruppe ausgibt , da die Mitgliedschaft auch von Benutzern stammt ' primäre Gruppen-ID , Mitgliedschaft nach Benutzer- UUID , Vererbung der Mitgliedschaft von einer Gruppe zu einer anderen und vom System berechnete Mitgliedschaften, z. B. die Gruppe " Jeder" .dscl . -read /Groups/mygroup GroupMembership

Anstatt zu versuchen, den Überblick zu behalten, scheint es eine bessere Idee zu sein, einfach die Mitgliedschaft jedes Benutzers im System zu überprüfen (mithilfe von dsmemberutil ), und genau das tun die Shell-Funktion und das folgende Skript.


Dieses Members- Skript entspricht der Shell-Funktion, hat jedoch eine bessere Behandlung ungültiger Eingaben:

#!/bin/bash

# members -- list all members of a group
#
# SYNOPSIS
#   members groupname
#
# http://superuser.com/questions/279891/list-all-members-of-a-group-mac-os-x
#  by Arne
# Expected to work on Mac OS 10.5 and newer, tested on 10.6 and 10.7.
# It could be rewritten to work on 10.4 by using "dseditgroup -o checkmember"
# instead of "dsmemberutil checkmembership".
# By using dseditgroup, the script could also be extended to handle
# other Directory Service nodes than the default local node.
#

the_group="$1"
# Input check and usage
  if [[ $# != 1 || $1 == -* || $1 =~ [[:space:]] ]]; then
    echo "Usage: ${0##*/} groupname" >&2
    echo "Lists all members of the group." >&2
    exit 64
  elif (dsmemberutil checkmembership -U root -G "$the_group" 2>&1 \
    | grep "group .* cannot be found") >&2; then
    exit 1
  fi

# Check every user
exec dscl . -list /Users \
  | while read each_username
  do
    printf "$each_username "
    dsmemberutil checkmembership -U "$each_username" -G "$the_group"
  done \
    | grep "is a member" | cut -d " " -f 1

# eof

Zusatzinfo:

Die fünf Möglichkeiten, ein Gruppenmitglied zu sein, sind:

  1. Die PrimaryGroupID des Benutzers
  2. In der GroupMembership der Gruppe aufgeführt
  3. UUID in den GroupMembers der Gruppe
  4. Vererbte Mitgliedschaft in Gruppe X durch Mitgliedschaft in Gruppe Y, die in den NestedGroups von Gruppe X aufgeführt ist
  5. Die Mitgliedschaft wird vom System berechnet

Diese können mit Befehlen wie erforscht werden dscl . -read /Groups/somegroup

Beispiel 4 : Mitgliedschaft in der Druckerbetreibergruppe __lpoperator_ wird von Mitgliedern der Druckadministratorgruppe __lpadmin_ übernommen, und die Mitgliedschaft in dieser Gruppe wird von Mitgliedern der Administratorgruppe übernommen .

Beispiel 5 :

$ dscl . -read /Groups/netaccounts Comment
Comment:
 Group membership calculated by system
 Accounts from a remote directory server
$ 

SIEHE AUCH
    id (1) , dscl (1) , dsmemberutil (1) , dseditgroup (8) , DirectoryServiceAttributes (7) , uuid (3)

Arne Stenström
quelle
7
Dies ist die Art von Eigentümlichkeiten, an die ich denke, wenn ich den Leuten sage, dass OS X, obwohl es an der Oberfläche großteils schön ist, unter der Decke einige üble Dinge versteckt hat.
Stefan Schmidt
+1 : Dies funktioniert solide. Merci.
Slipp D. Thompson
Dies ist die Information, die ich brauchte, um herauszufinden, wie ich mich aus der Admin-Gruppe entfernen kann. Es hat sich herausgestellt, dass das Entfernen nach Benutzername nicht ausreicht. Sie müssen auch die UUID entfernen (siehe github.com/drduh/macOS-Security-and-Privacy-Guide/issues/…
Jens Timmerman,
10

Hinweis: Dies war meine erste Antwort, die geschrieben wurde, bevor mir klar wurde, dass diese Antwort immer noch ein unvollständiges Ergebnis liefert . (Zum Beispiel findet es keine Mitglieder der Gruppe " Alle "!) Also schrieb ich eine bessere Antwort, die ein Skript enthält, das alle Mitglieder einer Gruppe in OS X auflistet .


Die GroupMembership -Eigenschaft von mygroup kann mit dscl wie folgt gedruckt werden :

dscl . -read /Groups/mygroup GroupMembership

Es ist jedoch nicht garantiert, dass alle (oder auch nur einige) Mitglieder der Gruppe ausgegeben werden. Was fehlt, sind die Benutzer, die nur dann Mitglied der Gruppe sind, wenn sie diese als primäre Gruppen-ID haben .

Ein häufiges Beispiel hierfür in OS X sind reguläre Anmeldekonten, deren primäre Gruppe Mitarbeiter (Gruppe 20) ist, die jedoch nicht in der GroupMembership-Eigenschaft der Mitarbeitergruppe aufgeführt sind.

Diese Benutzer können durch Suchen nach der numerischen Primärgruppen-ID (gid) wie im folgenden Beispiel für die Mitarbeitergruppe (gid 20) gefunden werden:

dscl . -list /Users PrimaryGroupID | grep " 20$"

und die numerische gid (PrimaryGroupID) von mygroup wird gefunden von:

dscl . -read /Groups/mygroup PrimaryGroupID
Arne Stenström
quelle
7

Um alle Gruppen abzurufen, denen ein Benutzer angehört , können Sie Folgendes verwenden:

id -nG <username>

Beispielausgabe:

staff com.apple.sharepoint.group.1 everyone localaccounts _appserverusr admin _appserveradm _lpadmin _appstore _lpoperator _developer com.apple.access_ftp com.apple.access_screensharing com.apple.access_ssh

Mit dem obigen Befehl können alle Benutzer abgerufen werden, die zu einer Gruppe gehören :

OSX :

group=staff;
for i in $(dscl . list /users);
do [[ $(id -nG $i | grep $group) ]] && echo $i;
done

Unix :

group=sudo;
# This only outputs lines that match a username (from the start of line to a colon must not be a hash indicating a comment) 
for i in $(grep -oE "^[^#:]+" /etc/passwd);
do [[ $(id -nG $i | grep $group) ]] && echo $i;
done
Jay Brown
quelle
Dies ist ein guter Tipp, um eine Liste der Gruppen zu erhalten, zu denen ein Benutzer gehört. Aber es ist das Gegenteil von dem, wonach das OP gefragt hat, nämlich die Liste der Benutzer, die zu einer Gruppe gehören.
wisbucky
@wisbucky das ist genau das, wonach ich gesucht habe. Ich habe hier gesucht, um "alle Gruppen eines Benutzers aufzulisten". Ich werde eine Änderung vorschlagen, um dies zu klären
Isaac
4

dscl . -read /Groups/[groupname] | grep GroupMembership

ACHTUNG: Der obige Befehl zeigt nicht immer eine vollständige Liste ALLER Gruppenmitglieder an. ZB für die Gruppe "staff" bekommt man als Gruppenmitglied nur "root", was unvollständig ist. Verwenden Sie zum Überprüfen einen der folgenden Befehle als Standardbenutzer (NICHT "root"): id -GnODERgroups

Als Ergebnis sehen Sie alle Gruppen, in denen Ihr standardmäßig angemeldeter Benutzer Mitglied ist. Einer von ihnen sollte "Mitarbeiter" sein. Somit gibt es neben "root" weitere Mitglieder der Gruppe "staff", die vom Befehl nicht aufgelistet werden dscl . -read /Groups/[groupname] | grep GroupMembership. Gleiches gilt für den Befehl, dscacheutil -q group -a name staffder auch darauf hindeutet, dass nur "root" Mitglied der Gruppe "staff" ist, was offensichtlich unvollständig ist.

Die einzig verlässliche Methode, um wirklich ALLE Mitglieder einer Gruppe in das Terminal auf OSX zu bekommen, bietet hier bereits Arne Stenström. Dies nutzt seine Shell-Funktion bzw. sein Shell-Skript. Beides funktioniert super!

William Jackson
quelle
1

Befehl

Ähnlich wie bei der Antwort von @ duperuser werden im Folgenden nur die Benutzer der Gruppe adminmit Leerzeichen dazwischen ausgedruckt :

dscacheutil -q group -a name admin | grep -e '^users:' | sed 's/users: //'

Ausgabe

Wenn Sie den obigen Befehl ausführen, erhalten Sie Folgendes:

root your_username someone_else

Nervenzusammenbruch

Mit dem dscacheutilBefehl werden Informationen zu verschiedenen Kategorien des Verzeichnisdienst-Cache des Systems abgefragt. Mit dieser -qOption können Sie die Kategorie angeben, die Sie abfragen möchten. Die verfügbaren Kategorien sind Gruppe, Host, Mount, Protokoll, RPC, Dienst und Benutzer. Wir fragen diese Kategorie weiter ab, indem wir ein Schlüsselwertpaar mit der -aOption angeben. In diesem Fall möchten wir die Gruppe auflisten, deren Schlüssel namedem Wert entspricht admin. Der dscacheutilobige Befehl erzeugt eine Ausgabe wie folgt:

name: admin
password: *
gid: 80
users: root yourusername

Als nächstes werden wir Rohr dieser Text in grepund die Zeile auswählen die Zeichenfolge enthält , users:am Anfang. Mit dieser -eOption erkennt grep reguläre Ausdrücke . Das ^Zeichen gibt an, dass wir users:am Anfang der Zeile stehen möchten .

Das gibt uns

users: root yourusername

Zum Schluss übergeben wir dies an sed und ersetzen den Text users:durch den leeren String. In seds bedeutet der erste Buchstabe zu ersetzen. Der Text zwischen dem ersten Paar Schrägstriche ( /users: /) soll ersetzt werden, und das nächste Paar Schrägstriche ( //) soll ersetzt werden (in diesem Fall nichts).

AmadeusDrZaius
quelle
0

Hier ist eine Implementierung für dieses Problem , das wurde abgeleitet von einer Implementierung in einer ähnlichen Diskussion . Die Routine ist etwas allgemein gehalten und verfügt über einen Verzeichnisdienst-Lookup-Hook für eine bestimmte Plattform / Architektur, sodass sie in einem heterogenen Netzwerk ohne Änderungen verwendet werden kann. Wir haben einen symbolischen Link zu diesem Dienstprogramm namens installiert zed. Andere Ursprünge für diese Implementierung werden im Attributionsabschnitt des Skripts erwähnt. Dieses Tool soll unter mindestens OSX, HP-UX, Linux und SunOS ausgeführt werden, war es aber noch nichtGetestet unter SunOS und HP-UX. Das Skript wurde so weit wie möglich unter Ubuntu Linux 12.04 und Mavericks OSX 10.9.1 getestet. Die Ausgabe dieses Skripts stimmt mit der Ausgabe für die erste Shell-Skriptimplementierung für dieses Problem überein und wird daher als korrekt betrachtet.

#!/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";
    }
}
Billy McCloskey
quelle