Как мне перечислить всех членов группы в Linux (и, возможно, других подразделений)?
Как мне перечислить всех членов группы в Linux (и, возможно, других подразделений)?
Ответы:
К сожалению, я не знаю хорошего, портативного способа сделать это. Если вы попытаетесь проанализировать / etc / group, как предлагают другие, вы пропустите пользователей, у которых эта группа является основной, и всех, кто был добавлен в эту группу с помощью механизма, отличного от плоских файлов UNIX (например, LDAP, NIS, pam-pgsql и т. д.).
Если бы мне абсолютно необходимо было сделать это самому, я бы, вероятно, сделал это наоборот: используйте id
для получения групп каждого пользователя в системе (который будет извлекать все источники, видимые для NSS) и используйте Perl или что-то подобное для поддержания хэша таблица для каждой обнаруженной группы, отмечающая членство этого пользователя.
Изменить: Конечно, это оставляет вас с похожей проблемой: как получить список каждого пользователя в системе. Поскольку мое местоположение использует только плоские файлы и LDAP, я могу просто получить список из обоих местоположений, но это может или не может быть правдой для вашей среды.
Изменить 2: Кто-то мимоходом напомнил мне, что getent passwd
вернет список всех пользователей в системе, включая пользователей из LDAP / NIS / и т. Д., Но 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 (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";
}
}
getent passwd
могут не работать (если, например, вы используете sssd).
getent passwd
я бы посчитал это ошибкой в sssd.
Используйте Python для вывода списка участников группы:
python -c "импорт grp; печать grp.getgrnam ('GROUP_NAME') [3]"
lid -g groupname | cut -f1 -d'('
Следующая команда выведет список всех пользователей, принадлежащих <your_group_name>
, но только тех, кто управляется /etc/group
базой данных, но не LDAP, NIS и т. Д. Она также работает только для вторичных групп , она не будет перечислять пользователей, для которых эта группа установлена в качестве основной, поскольку основная группа хранится как GID
(числовой идентификатор группы) в файле /etc/passwd
.
grep <your_group_name> /etc/group
Следующая команда выведет список всех пользователей, принадлежащих <your_group_name>
, но только тех, кто управляется /etc/group
базой данных, но не LDAP, NIS и т. Д. Она также работает только для вторичных групп , она не будет перечислять пользователей, для которых эта группа установлена в качестве основной, поскольку основная группа хранится как GID
(числовой идентификатор группы) в файле /etc/passwd
.
awk -F: '/^groupname/ {print $4;}' /etc/group
Следующий скрипт оболочки будет перебирать всех пользователей и печатать только те имена пользователей, которые принадлежат данной группе:
#!/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
Пример использования:
./script 'DOMAIN+Group Name'
Примечание: Это решение будет проверять NIS и LDAP для пользователей и групп (не только passwd
и group
файлов). Также будут учитываться пользователи, не добавленные в группу, но имеющие группу, установленную в качестве основной группы.
Изменить: Добавлено исправление для редкого сценария, когда пользователь не принадлежит к группе с тем же именем.
Редактировать: написано в виде сценария оболочки; добавлено true
для выхода со 0
статусом, предложенным @Max Chernyak aka hakunin ; отбрасывается stderr
, чтобы пропустить те случайные groups: cannot find name for group ID xxxxxx
.
; true
. Возвращать 0 - это хорошо, чтобы избежать отключения вашей системы управления конфигурацией (Chef, Ansible и т. Д.).
Вы можете сделать это в одной командной строке:
cut -d: -f1,4 /etc/passwd | grep $(getent group <groupname> | cut -d: -f3) | cut -d: -f1
Команда выше перечисляет всех пользователей, имеющих имя группы в качестве основной группы
Если вы также хотите перечислить пользователей, имеющих имя группы в качестве своей вторичной группы, используйте следующую команду
getent group <groupname> | cut -d: -f4 | tr ',' '\n'
grep
будет соответствовать пользователю, чье имя содержит номер группы (например, sc0tt
будет отображаться как часть root
группы). Если это проблема, используйте регулярное выражение :$(getent group <groupname> | cut -d: -f3)\$
(соответствует точке с запятой, идентификатору группы и концу строки). (Не добавляйте цитаты к регулярному выражению, или Баш жалуется.)
Реализация 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'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";
}
}
Если есть лучший способ поделиться этим предложением, пожалуйста, дайте мне знать; Я рассмотрел много способов, и это то, что я придумал.
id -Gn
на/usr/xpg4/bin/id -G -n
Я сделал это аналогично приведенному выше коду 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";
Существует удобный пакет Debian и Ubuntu, называемый ' members ', который обеспечивает эту функциональность:
Описание: показывает участников группы; по умолчанию все члены-члены являются дополнением к группам: в то время как группы показывают группы, к которым принадлежит указанный пользователь, участники показывают пользователей, принадлежащих к указанной группе.
... Вы можете запросить первичных, вторичных участников, как на одной строке, так и на каждой отдельной строке.
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')")
Вот скрипт, который возвращает список пользователей из / 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
В UNIX (в отличие от GNU / Linux) есть команда listusers. См. Справочную страницу Solaris для пользователей списков .
Обратите внимание, что эта команда является частью проекта Heirloom с открытым исходным кодом . Я предполагаю, что это отсутствует в GNU / Linux, потому что RMS не верит в группы и разрешения. :-)
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.
Вот очень простой сценарий awk, который учитывает все распространенные ошибки, перечисленные в других ответах:
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.
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
, если пользователей слишком много.
С уважением
Я думаю, что самым простым способом являются следующие шаги, вам не нужно устанавливать какой-либо пакет или программное обеспечение:
Во-первых, вы узнаете GID группы, которую вы хотите знать пользователям, для этого есть много способов: cat / etc / group (последний столбец - GID) id user (пользователь - это тот, кто принадлежит группа)
Теперь вы перечислите всех пользователей в файле / etc / passwd, но вы примените некоторые фильтры со следующим набором команд, чтобы получить только членов предыдущей группы.
cut -d: -f1,4 / etc / passwd | grep GID (GID - это число, которое вы получили на шаге 1)
Команда cut выберет только некоторые «столбцы» файла, параметр d устанавливает разделитель «:», в этом случае параметр -f выбирает «поля» (или столбцы), которые будут показаны 1 и 4 в случае выхода (вкл. файл / etc / passwd, столбец 1º - это имя пользователя, а 4º - это GID группы, к которой принадлежит пользователь), чтобы завершить | grep GID отфильтрует только группу (в столбце 4º), которую вы выбрал.
Вот еще один однострочник Python, который учитывает членство пользователя в группе по умолчанию (из /etc/passwd
), а также из базы данных группы ( /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]])"
Я пытался grep 'sample-group-name' /etc/group
, что будет перечислять всех членов группы, которую вы указали на основе примера здесь
/etc/group
есть как минимум в 3 других ответах, какую ценность ваш ответ добавляет к ним? Кроме того, все остальные ответы содержат комментарии о том, что такое решение работает только для вторичных групп, а также не для учетной записи, управляемой LDAP, NIS и т. Д.