Как составить список всех пользователей в группе Linux?

244

Как мне перечислить всех членов группы в Linux (и, возможно, в других организациях)?

  • 1
    @ Silmari89, Нет, если он хочет сделать это программно.
  • 2
    Я новичок здесь, я узнал, что SF существует сразу после того, как я отправил вопрос. Я согласен, что это принадлежит либо SF, либо SO.
Показать ещё 1 комментарий
Теги:
user
groups

18 ответов

93
Лучший ответ

К сожалению, нет хорошего, переносного способа сделать это, о котором я знаю. Если вы попытаетесь разобрать /etc/group, как указывают другие, вы пропустите пользователей, у которых есть группа в качестве основной группы, и всех, кто был добавлен в эту группу с помощью механизма, отличного от плоских файлов UNIX (то есть LDAP, NIS, pam-pgsql и т.д.).

Если бы я сам должен был сделать это сам, я бы сделал это наоборот: используйте id, чтобы получить группы каждого пользователя в системе (которые будут тянуть все источники, видимые для NSS), и использовать Perl или что-то похожее на сохранение хеш-таблицы для каждой группы, которая обнаружила членство этого пользователя.

Изменить: Конечно, это оставляет вам аналогичную проблему: как получить список каждого пользователя в системе. Поскольку в моем местоположении используются только плоские файлы и LDAP, я могу просто получить список из обоих мест, но это может быть или не быть истинным для вашей среды.

Отредактируйте 2: кто-то мимоходом напомнил мне, что getent passwd вернет список всех пользователей в системе, включая имена из LDAP/NIS/etc., но getent group по-прежнему будут пропускать пользователей, которые являются членами только через по умолчанию, так что это вдохновило меня написать этот быстрый хак.


#!/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 ([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";

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
    Спасибо всем, кто ответил. Я искал портативный способ сделать это. Ваша информация о том, что нет простого и переносимого способа, была полезна. Вы также подробно рассказали об обстоятельствах, которые помогли мне глубже понять проблему, я ценю это и выбрал ваш ответ в качестве принятого.
  • 2
    Вы могли бы пожертвовать свой сценарий в фонд Linux? Это 2012 год, и до сих пор нет простого способа получить членов группы. Это то, что разочаровывает меня в Linux.
Показать ещё 6 комментариев
206
getent group <groupname>;

Он переносится как в Linux, так и в Solaris, и работает с файлами локальных групп/паролей, NIS и LDAP.

  • 0
    Спасибо, но это уже упоминалось в посте Зеда.
  • 39
    Не показывает пользователей, которые имеют группу в качестве группы по умолчанию.
34

Использовать Python для отображения групп:

python -c "import grp; print grp.getgrnam('GROUP_NAME') [3]"

См. https://docs.python.org/2/library/grp.html

  • 0
    К сожалению, не сообщает о членах группы домена.
34
lid -g groupname | cut -f1 -d'(' 
  • 7
    Это был бы самый хороший способ, за исключением того, что lid не входит в стандартную установку Debian. В Ubuntu он находится в дополнительном пакете libuser (это не тот пакет в id-utils с тем же именем). Я не нашел его в Debian :(
  • 0
    Работал для меня на Scientific Linux
Показать ещё 8 комментариев
22

Следующая команда перечисляет всех пользователей, относящихся к <your_group_name>, но только те, которые управляются базой данных /etc/group, а не LDAP, NIS и т.д. Он также работает только для вторичных групп, он выиграл 't укажите пользователей, у которых эта группа установлена ​​как первичная, поскольку первичная группа хранится как GID (числовой идентификатор группы) в файле /etc/passwd.

grep <your_group_name> /etc/group
  • 1
    Работал на OSX! ура
  • 4
    Вы можете использовать grep непосредственно в этот файл, например, grep <username> / etc / group. Быстрее и меньше накладных расходов.
Показать ещё 1 комментарий
16

Следующая команда перечисляет всех пользователей, относящихся к <your_group_name>, но только те, которые управляются базой данных /etc/group, а не LDAP, NIS и т.д. Он также работает только для вторичных групп, он выиграл 't укажите пользователей, у которых эта группа установлена ​​как первичная, поскольку первичная группа хранится как GID (числовой идентификатор группы) в файле /etc/passwd.

awk -F: '/^groupname/ {print $4;}' /etc/group
  • 7
    Не показывает пользователей, которые имеют группу в качестве группы по умолчанию.
  • 3
    Не проверяет NIS и LDAP.
8

Следующий фрагмент оболочки будет проходить через всех пользователей и печатать только те имена пользователей, которые относятся к указанному $group.

getent passwd | while IFS=: read name trash
do
    groups $name | cut -f2 -d: | grep -q -w "$group" && echo $name
done

Примечание.. Это решение проверит NIS и LDAP для пользователей и групп (а не только файлы passwd и group). Он также будет учитывать пользователей, не добавленных в группу, но имеющих группу в качестве основной группы.

Изменить: Добавлено исправление для редкого сценария, в котором пользователь не принадлежит к группе с тем же именем.

  • 0
    Это здорово и очень кратко, но печатает как имя группы, так и имена пользователей
  • 0
    @andrewlorien, надеюсь, я исправил упомянутую вами проблему, если нет, то предоставьте более подробную информацию.
Показать ещё 4 комментария
4

Вы можете сделать это в одной командной строке:

cut -d: -f1,4 /etc/passwd | grep $(getent group <groupname> | cut -d: -f3) | cut -d: -f1

В приведенной выше команде перечислены все пользователи, имеющие groupname в качестве своей основной группы

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

getent group <groupname> | cut -d: -f4 |  tr ',' '\n'
  • 1
    Предостережение: grep будет соответствовать пользователю, имя которого содержит номер группы (например, sc0tt будет отображаться как часть root группы). Если это проблема, используйте регулярное выражение :$(getent group <groupname> | cut -d: -f3)\$ (соответствует :$(getent group <groupname> | cut -d: -f3)\$ с запятой, идентификатору группы и концу строки). (Не добавляйте цитаты в регулярные выражения, или Баш жалуется.)
  • 0
    @ Скоттс Законное падение. Рекомендую предложенные шаги
3

Я сделал это похоже на код perl выше, но заменил getent и id на собственные функции perl. Это намного быстрее и должно работать в разных вариантах * nix.

#!/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";
  • 0
    Ответ со ссылкой только не считается хорошим ответом при переполнении стека. Пожалуйста, рассмотрите возможность удаления этого, поскольку это не дает ответа на вопрос или более подробно описывает, насколько этот ответ лучше принятого ответа. Или вы можете добавить это как комментарий, как только у вас будет достаточно репутации. Вы всегда можете комментировать свои собственные сообщения.
  • 0
    Я заменил ссылку с кодом.
3

Zed-реализация должна, вероятно, быть расширена для работы с некоторыми другими крупными UNIX.

Кто-то имеет доступ к оборудованию Solaris или HP-UX?; не проверяли эти случаи.

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

Если есть лучший способ поделиться этим предложением, пожалуйста, дайте мне знать; Я рассмотрел множество способов, и это то, что я придумал.

  • 0
    Подтвердили работу на Solaris 10 после изменения id -Gn на /usr/xpg4/bin/id -G -n
3

немного grep и tr:

$ grep ^$GROUP /etc/group | grep -o '[^:]*$' | tr ',' '\n'
user1
user2
user3
  • 4
    Не показывает пользователей, которые имеют группу в качестве группы по умолчанию.
2

Существует удобный пакет Debian и Ubuntu с именем members ", который обеспечивает эту функциональность:

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

... Вы можете попросить первичных участников, второстепенных участников, как на  одна строка, каждая на отдельных строках.

  • 0
    Что если в опе используется openwrt?
  • 0
    Действительно удобно, но, к сожалению, не сообщает о членах группы домена.
0
getent group groupname | awk -F: '{print $4}' | tr , '\n'

Это имеет 3 части:

1 - getent group groupname показывает строку группы в файле "/etc/group". Альтернатива cat /etc/group | grep groupname.

2 - awk печатать только элементы в одной строке, разделенные символом ','.

3 - tr замените ',' на новую строку и напечатайте каждого пользователя в строке.

4 - Необязательно: вы также можете использовать другой канал с sort, если пользователей слишком много.

Привет

0
getent group insert_group_name_here | awk -F ':' '{print $4}' | sed 's|,| |g'

Это возвращает список разделенных пробелами пользователей, которые я использовал в сценариях для заполнения массивов.

for i in $(getent group ftp | awk -F ':' '{print $4}' | sed 's|,| |g')
    do
        userarray+=("$i")
    done

или

userarray+=("$(getent group GROUPNAME | awk -F ':' '{print $4}' | sed 's|,| |g')")
0

Я пробовал grep 'sample-group-name' /etc/group, который отобразит список всех членов указанной вами группы на примере здесь

  • 1
    Grepping /etc/group есть как минимум в 3 других ответах, какую ценность ваш ответ добавляет к ним? Кроме того, все остальные ответы содержат комментарии о том, что такое решение работает только для вторичных групп, а также не для учетной записи, управляемой LDAP, NIS и т. Д.
0

Здесь очень простой awk script, который учитывает все распространенные ошибки, перечисленные в других ответах:

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}'

Я использую это с моей настройкой с поддержкой ldap, работает на любом уровне, совместимом со стандартами getent и awk, включая solaris 8+ и hpux.

0

В UNIX (в отличие от GNU/Linux) есть команда listusers. См. справочная страница Solaris для пользователей-пользователей.

Обратите внимание, что эта команда является частью проекта проекта Heirloom. Я предполагаю, что он отсутствует в GNU/Linux, потому что RMS не верит в группы и разрешения.: -)

  • 1
    Хотя эта ссылка может ответить на вопрос, лучше включить сюда основные части ответа и предоставить ссылку для справки. Ответы, содержащие только ссылки, могут стать недействительными в случае изменения связанной страницы. - Из обзора
  • 0
    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.
Показать ещё 1 комментарий
0

Вот script, который возвращает список пользователей из /etc/passwd и/etc/group он не проверяет NIS или LDAP, но показывает пользователей, у которых группа в качестве группы по умолчанию Протестировано на Debian 4.7 и solaris 9

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

или как однострочный вы можете вырезать и вставлять прямо отсюда (изменить имя группы в первой переменной)

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

Ещё вопросы

Сообщество Overcoder
Наверх
Меню