Список всех членов группы (Mac OS X)

56

Я пробовал гуглить, но никуда не денешься. Как я могу перечислить всех членов группы, вызванной mygroupиз командной строки в OS X?

$ dscl . list /groupsдостанет мне все группы ... но как я могу увидеть участников каждой группы?

Мельтеми
источник

Ответы:

41

Вы можете использовать:

dscacheutil -q group -a name admin

или же:

dscacheutil -q group -a name staff

и т.п.

duperuser
источник
Это мой любимый метод. Легко и аккуратно, и аккуратно. Спасибо!
TryTryAgain
Это отличный ответ, поскольку 90% случаев использования могут быть решены с помощью этого, а не с помощью более сложных сценариев, которые были опубликованы в качестве ответов.
JakeGould
Просто добавьте это как псевдоним в свой файл запуска оболочки, и вы можете сделать это командой из одного слова плюс имя группы.
Нил Монро
Когда я попробовал "dscacheutil -q group", я получил 2 абзаца для группы "admin". У обоих одинаковое имя, gid, но разные пользователи. Любая идея? Спасибо!
Золотой палец
Не обязательно завершено. dscacheutil -q group -a name adminтолько дал мне 1 результат, в то время как сценарий оболочки принятого ответа дал мне 2 результата.
wisbucky
64

Там нет стандартной команды, которая перечисляет всех членов группы в OS X, поэтому вот функция оболочки, которая делает это:

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

Скопируйте приведенную выше командную строку в терминал и введите (где mygroup - это имя существующей группы).members mygroup


Некоторое объяснение для тех, кто заинтересован:

Существует пять различных способов (о которых я знаю), что пользователь может быть членом группы в OS X. Команда не гарантирует вывод всех или даже любых членов mygroup , поскольку членство также исходит от пользователей. « первичная группа ID , членство пользователя UUID , наследование членства из одной группы в другую, а также членство, которые вычисляются системой, такие как группа всех .dscl . -read /Groups/mygroup GroupMembership

Поэтому вместо того, чтобы пытаться отслеживать все это, лучше всего просто проверить членство каждого пользователя в системе (используя dsmemberutil ), и именно это делают функция оболочки и приведенный ниже скрипт.


Этот скрипт- член эквивалентен функции оболочки, но имеет лучшую обработку неверного ввода:

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

Дополнительная информация:

Пять способов быть членом группы:

  1. PrimaryGroupID пользователя
  2. Перечислено в группы GroupMembership
  3. UUID перечислены в группы GroupMembers
  4. Унаследованное членство в группе X, будучи членом группы Y, которая указана в NestedGroups группы X
  5. Членство рассчитывается системой

Это можно изучить с помощью команд, таких как dscl . -read /Groups/somegroup

Пример 4. Членство в группе операторов печати __lpoperator_ наследуется членами группы администраторов печати __lpadmin_, а членство в этой группе наследуется членами группы администраторов .

Пример 5 :

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

СМОТРИ ТАКЖЕ
    id (1) , dscl (1) , dsmemberutil (1) , dseditgroup (8) , DirectoryServiceAttributes (7) , uuid (3)

Арне Стенстрём
источник
7
Это те особенности, которые я имею в виду, когда говорю людям, что, хотя OS X в основном красива на поверхности, под крышками скрываются некоторые неприятные вещи.
Стефан Шмидт
+1 : это работает надежно. Merci.
Слипп Д. Томпсон
Это информация, которая мне нужна, чтобы понять, как удалить себя из группы администраторов. Оказывается, удаление по имени пользователя не достаточно, вам также нужно удалить UUID, см. Github.com/drduh/macOS-Security-and-Privacy-Guide/issues/…
Йенс Тиммерман,
10

Примечание. Это был мой первоначальный ответ, написанный до того, как я понял, что этот ответ по-прежнему дает неполный результат . (Например, он не находит членов каждой группы!) Так что я написал лучший ответ, который включает в себя сценарий , который содержит список всех член группы в OS X .


Свойство GroupMembership mygroup может быть напечатано с помощью dscl следующим образом:

dscl . -read /Groups/mygroup GroupMembership

Но это не гарантирует вывод всех (или даже любых) членов группы. Чего не хватает, так это пользователей, которые являются членами группы, только имея ее в качестве идентификатора своей основной группы .

Типичным примером этого в OS X являются обычные учетные записи, которые имеют сотрудников (группа 20) в качестве своей основной группы, но не перечислены в свойстве GroupMembership группы персонала .

Этих пользователей можно найти, выполнив поиск числового идентификатора первичной группы (gid), как в этом примере для группы персонала (gid 20):

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

и числовой идентификатор (PrimaryGroupID) mygroup находится:

dscl . -read /Groups/mygroup PrimaryGroupID
Арне Стенстрём
источник
7

Чтобы получить все группы, в которые входит пользователь , вы можете использовать следующее:

id -nG <username>

Пример вывода:

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

Используя приведенную выше команду, можно получить всех пользователей, принадлежащих к группе :

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
Джей Браун
источник
Это хороший совет, чтобы получить список групп, к которым принадлежит пользователь. Но это противоположность того, о чем спрашивал ОП: список пользователей, принадлежащих к группе.
wisbucky
@wisbucky это именно то, что я был после. Я попал сюда в поисках "список всех групп пользователя". Я предлагаю внести изменения, чтобы уточнить это
Исаак
4

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

ВНИМАНИЕ: Команда выше не всегда отображает полный список ВСЕХ членов группы. Например, для группы "staff" вы получаете только "root" в качестве участника группы, который является неполным. Для проверки используйте одну из следующих команд в качестве пользователя по умолчанию (НЕ «root»): id -GnИЛИgroups

В результате вы увидите все группы, в которые входит ваш зарегистрированный пользователь по умолчанию. Одним из них должен быть «персонал». Таким образом, помимо «root» есть еще члены группы «staff», которые не перечислены командой dscl . -read /Groups/[groupname] | grep GroupMembership. То же самое касается команды, dscacheutil -q group -a name staffкоторая также предполагает, что только «root» является членом группы «staff», что, очевидно, является неполным.

Единственный надежный способ получить действительно ВСЕХ членов группы в терминале на OSX уже предоставлен здесь Арне Стенстрём. Это использует его функцию оболочки соответственно его сценарий оболочки. Оба прекрасно работают!

Уильям Джексон
источник
1

команда

Как и в ответе @ duperuser, следующее будет выводить только пользователей группы adminс пробелами между ними:

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

Выход

Выполнение вышеупомянутой команды выдаст что-то вроде этого:

root your_username someone_else

Сломать

Команда dscacheutilиспользуется для запроса информации о различных категориях системного кэша службы каталогов. -qОпция позволяет указать категорию , которую хотите запросить. Доступные категории: группа, хост, монтирование, протокол, RPC, сервис и пользователь. Далее мы запросим эту категорию, указав пару ключ-значение с -aпараметром. В этом случае мы хотим перечислить группу, ключ которой nameравен значению admin. Команда dscacheutilвыше производит вывод как это:

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

Затем мы передаем этот текст по конвейеруgrep и выбираем строку, содержащую строку users:в начале. В -eопции делает Grep распознавать регулярные выражения . Символ ^указывает, что мы хотим users:быть в начале строки.

Это дает нам

users: root yourusername

Наконец, мы передаем это в sed и заменяем текст users:пустой строкой. В седе первая буква sозначает замену. Текст между первой парой слешей ( /users: /) - это то, что мы хотим заменить, а следующая пара слешей ( //) - это то, что мы хотим заменить (в данном случае, ничего).

AmadeusDrZaius
источник
0

Вот реализация этой проблемы, которая была получена из реализации в связанном обсуждении . Процедура является несколько общей, с ловушкой поиска службы каталогов для любой конкретной платформы / архитектуры, поэтому ее можно использовать без изменений в гетерогенной сети. Мы установили символическую ссылку на эту утилиту с именем zed. Другие источники этой реализации упоминаются в разделе атрибуции скрипта. Этот инструмент предназначен для работы по крайней мере на OSX, HP-UX, Linux и SunOS, но не былпротестировано на SunOS и HP-UX. Скрипт был максимально протестирован на Ubuntu Linux 12.04 и Mavericks OSX 10.9.1. Выходные данные этого сценария совпадают с выходными данными для первой реализации сценария оболочки для этой проблемы и поэтому считаются правильными.

#!/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";
    }
}
Билли Макклоски
источник