Wyświetl listę wszystkich członków grupy (Mac OS X)

56

Próbowałem google, ale nigdzie się nie dostałem. Jak mogę wyświetlić listę wszystkich członków grupy wywoływanych mygroupz wiersza poleceń w OS X?

$ dostarczy dscl . list /groupsmi wszystkie grupy ... ale jak mogę zobaczyć członków każdej grupy?

Meltemi
źródło

Odpowiedzi:

40

Możesz użyć:

dscacheutil -q group -a name admin

lub:

dscacheutil -q group -a name staff

itp.

duperuser
źródło
To moja ulubiona metoda. Łatwy peasy i dokładny. Dzięki!
TryTryAgain
To świetna odpowiedź, ponieważ 90% przypadków użycia można rozwiązać za pomocą tego, a nie bardziej skomplikowanych skryptów, które zostały opublikowane jako odpowiedzi.
JakeGould,
Po prostu dodaj to jako alias w swoim pliku startowym powłoki i możesz uczynić z niego jedno słowo i nazwę grupy.
Neil Monroe
Kiedy próbowałem „dscacheutil -q group”, otrzymałem 2 akapity dla grupy „admin”. Obaj mają tę samą nazwę, gid, ale listę różnych użytkowników. Dowolny pomysł? Dzięki!
Złoty Kciuk
Niekoniecznie ukończone. dscacheutil -q group -a name admindał mi tylko 1 wynik, podczas gdy skrypt powłoki odpowiedzi zaakceptowanej dał mi 2 wyniki.
wisbucky
64

Nie ma standardowego polecenia, które wyświetla listę wszystkich członków grupy w OS X, więc oto funkcja powłoki, która to robi:

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

Skopiuj powyższy wiersz polecenia do terminala, a następnie wpisz (gdzie mygroup to nazwa istniejącej grupy).members mygroup


Niektóre wyjaśnienia dla zainteresowanych:

Istnieje pięć różnych sposobów (o których wiem), że użytkownik może być członkiem grupy w OS X. Polecenie to nie gwarantuje wypisania wszystkich, a nawet któregokolwiek z członków mojej grupy, ponieważ członkostwo również pochodzi od użytkowników „ identyfikator grupy podstawowej , członkostwo według UUID użytkownika , dziedziczenie członkostwa z jednej grupy do drugiej oraz członkostwa obliczane przez system, takie jak grupa wszyscy .dscl . -read /Groups/mygroup GroupMembership

Zamiast więc śledzić to wszystko, lepszym pomysłem wydaje się po prostu sprawdzenie członkostwa każdego użytkownika w systemie (za pomocą dsmemberutil ), i to właśnie robią funkcja powłoki i poniższy skrypt.


Ten skrypt członków jest równoważny funkcji powłoki, ale ma lepszą obsługę nieprawidłowych danych wejściowych:

#!/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

Informacje dodatkowe:

Pięć sposobów bycia członkiem grupy to:

  1. PrimaryGroupID użytkownika
  2. Wymienione w GroupMembership grupy
  3. UUID wymieniony w GroupMembers grupy
  4. Dziedziczone członkostwo w grupie X przez bycie członkiem grupy Y, która jest wymieniona w grupach zagnieżdżonych grupy X.
  5. Członkostwo obliczane przez system

Można je zbadać za pomocą poleceń takich jak dscl . -read /Groups/somegroup

Przykład 4 : członkostwo w grupie operatorów drukowania __lpoperator_ jest dziedziczone przez członków grupy Administrator wydruku __lpadmin_, a członkostwo w tej grupie jest dziedziczone przez członków grupy administracyjnej .

Przykład 5 :

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

ZOBACZ TAKŻE
    id (1) , dscl (1) , dsmemberutil (1) , dseditgroup (8) , DirectoryServiceAttributes (7) , uuid (3)

Arne Stenström
źródło
7
Jest to rodzaj osobliwości, o której myślę, gdy mówię ludziom, że chociaż OS X jest w większości piękny na powierzchni, pod przykryciem kryje się kilka nieprzyjemnych rzeczy.
Stefan Schmidt
+1 : Działa solidnie. Merci.
Slipp D. Thompson,
To są informacje, których potrzebowałem, aby dowiedzieć się, jak usunąć się z grupy administratorów. Okazuje się, że usunięcie według nazwy użytkownika nie wystarczy, musisz także usunąć UUID, patrz github.com/drduh/macOS-Security-and-Privacy-Guide/issues/…
Jens Timmerman
10

Uwaga: To była moja pierwsza odpowiedź, napisana zanim zdałem sobie sprawę, że ta odpowiedź wciąż daje niepełny wynik . (Na przykład, to nie znajdzie członków everyone grupy!) Więc napisałem lepszą odpowiedź, która zawiera skrypt, który zawiera listę wszystkich członków grupy w OS X .


Właściwość GroupMembership mygroup można wydrukować za pomocą dscl w następujący sposób:

dscl . -read /Groups/mygroup GroupMembership

Ale nie ma gwarancji, że wygeneruje wszystkie (lub nawet) członków grupy. Brakuje użytkowników, którzy są członkami grupy tylko wtedy, gdy są jej głównym identyfikatorem grupy .

Typowym przykładem tego w systemie OS X są zwykłe konta logowania, które mają personel (grupa 20) jako podstawową grupę, ale nie są wymienione we właściwości GroupMembership grupy pracowników .

Tych użytkowników można znaleźć, wyszukując numeryczny identyfikator grupy podstawowej (gid), jak w tym przykładzie dla grupy pracowników (gid 20):

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

a numeryczny gid (PrimaryGroupID) mojej grupy znajduje się przez:

dscl . -read /Groups/mygroup PrimaryGroupID
Arne Stenström
źródło
7

Aby uzyskać wszystkie grupy, w których znajduje się użytkownik , możesz użyć następujących opcji:

id -nG <username>

Przykładowe dane wyjściowe:

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

Korzystając z powyższego polecenia, można uzyskać wszystkich użytkowników należących do grupy :

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
źródło
To dobra wskazówka, aby uzyskać listę grup, do których należy użytkownik. Jest to jednak przeciwieństwo tego, o co prosi OP, czyli listy użytkowników należących do grupy.
wisbucky
@wisbucky właśnie o to mi chodziło. Przybyłem tutaj, szukając „listy wszystkich grup użytkownika”. Zasugeruję edycję, aby to wyjaśnić
Izaak
4

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

UWAŻAJ: powyższe polecenie nie zawsze wyświetla pełną listę WSZYSTKICH członków grupy. Np. Dla „personelu” grupy otrzymujesz „root” jako członek grupy, który jest niekompletny. Aby to sprawdzić, użyj jednego z następujących poleceń jako domyślny użytkownik (NIE „root”): id -GnLUBgroups

W rezultacie zobaczysz wszystkie grupy, do których należy domyślnie zalogowany użytkownik. Jednym z nich powinien być „personel”. Zatem oprócz „root” jest więcej członków grupy „staff”, którzy nie są wymienieni w poleceniu dscl . -read /Groups/[groupname] | grep GroupMembership. To samo dotyczy polecenia, dscacheutil -q group -a name staffktóre sugeruje również, że tylko „root” jest członkiem grupy „staff”, co jest oczywiście niekompletne.

Jedyną niezawodną metodą uzyskania naprawdę WSZYSTKICH członków grupy w terminalu na OSX jest już tutaj Arne Stenström. To używa jego funkcji powłoki lub. jego skrypt powłoki. Oba działa świetnie!

William Jackson
źródło
1

Komenda

Podobnie do odpowiedzi @ duperuser, następujący wydrukuje tylko użytkowników grupy adminze spacjami między nimi:

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

Wynik

Uruchomienie powyższego polecenia spowoduje wygenerowanie czegoś takiego:

root your_username someone_else

Awaria

dscacheutilPolecenie służy do kwerendy informacji o różnych kategoriach systemu usługi katalogowej pamięci podręcznej. Ta -qopcja pozwala określić kategorię, którą chcesz zapytać. Dostępne kategorie to grupa, host, podłączenie, protokół, rpc, usługa i użytkownik. Następnie przeszukujemy tę kategorię, podając parę klucz-wartość z -aopcją. W tym przypadku chcemy wymienić grupę mającą klucz namerówny wartości admin. Powyższe dscacheutilpolecenie generuje dane wyjściowe w następujący sposób:

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

Następnie potokujemy ten tekst grepi wybieramy wiersz zawierający ciąg users:na początku. Ta -eopcja powoduje, że grep rozpoznaje wyrażenia regularne . ^Charakter określa, że chcemy users:być na początku wiersza.

To nam daje

users: root yourusername

Na koniec przekazujemy to do sed i zastępujemy tekst users:pustym ciągiem. W sed pierwsza litera soznacza zamiennik. Tekst między pierwszą parą ukośników ( /users: /) jest tym, co chcemy zastąpić, a następna para ukośników ( //) jest tym, co chcemy zastąpić (w tym przypadku nic).

AmadeusDrZaius
źródło
0

Oto implementacja tego problemu, która pochodzi z implementacji w powiązanej dyskusji . Procedura jest dość ogólna, z hakiem wyszukiwania usługi katalogowej dla dowolnej konkretnej platformy / architektury, więc można jej używać bez modyfikacji w sieci heterogenicznej. Zainstalowaliśmy symboliczne łącze do tego narzędzia o nazwie zed. Inne źródła tej implementacji są wymienione w sekcji dotyczącej atrybucji skryptu. To narzędzie jest przeznaczone do uruchamiania na przynajmniej OSX, HP-UX, Linux i SunOS, ale nie byłoprzetestowany na SunOS i HP-UX. Skrypt został przetestowany w miarę możliwości na Ubuntu Linux 12.04 i Mavericks OSX 10.9.1. Dane wyjściowe tego skryptu są zgodne z danymi wyjściowymi pierwszej implementacji skryptu powłoki dla tego problemu i dlatego są uważane za poprawne.

#!/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
źródło