Как мне перечислить всех членов группы в Linux (и, возможно, в других организациях)?
К сожалению, нет хорошего, переносного способа сделать это, о котором я знаю. Если вы попытаетесь разобрать /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";
}
}
getent group <groupname>;
Он переносится как в Linux, так и в Solaris, и работает с файлами локальных групп/паролей, NIS и LDAP.
Использовать Python для отображения групп:
python -c "import grp; print grp.getgrnam('GROUP_NAME') [3]"
lid -g groupname | cut -f1 -d'('
Следующая команда перечисляет всех пользователей, относящихся к <your_group_name>
, но только те, которые управляются базой данных /etc/group
, а не LDAP, NIS и т.д. Он также работает только для вторичных групп, он выиграл 't укажите пользователей, у которых эта группа установлена как первичная, поскольку первичная группа хранится как GID
(числовой идентификатор группы) в файле /etc/passwd
.
grep <your_group_name> /etc/group
Следующая команда перечисляет всех пользователей, относящихся к <your_group_name>
, но только те, которые управляются базой данных /etc/group
, а не LDAP, NIS и т.д. Он также работает только для вторичных групп, он выиграл 't укажите пользователей, у которых эта группа установлена как первичная, поскольку первичная группа хранится как GID
(числовой идентификатор группы) в файле /etc/passwd
.
awk -F: '/^groupname/ {print $4;}' /etc/group
Следующий фрагмент оболочки будет проходить через всех пользователей и печатать только те имена пользователей, которые относятся к указанному $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
). Он также будет учитывать пользователей, не добавленных в группу, но имеющих группу в качестве основной группы.
Изменить: Добавлено исправление для редкого сценария, в котором пользователь не принадлежит к группе с тем же именем.
Вы можете сделать это в одной командной строке:
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'
grep
будет соответствовать пользователю, имя которого содержит номер группы (например, sc0tt
будет отображаться как часть root
группы). Если это проблема, используйте регулярное выражение :$(getent group <groupname> | cut -d: -f3)\$
(соответствует :$(getent group <groupname> | cut -d: -f3)\$
с запятой, идентификатору группы и концу строки). (Не добавляйте цитаты в регулярные выражения, или Баш жалуется.)
Я сделал это похоже на код 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";
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";
}
}
Если есть лучший способ поделиться этим предложением, пожалуйста, дайте мне знать; Я рассмотрел множество способов, и это то, что я придумал.
id -Gn
на /usr/xpg4/bin/id -G -n
немного grep и tr:
$ grep ^$GROUP /etc/group | grep -o '[^:]*$' | tr ',' '\n'
user1
user2
user3
Существует удобный пакет Debian и Ubuntu с именем members ", который обеспечивает эту функциональность:
Описание: Показывает членов группы; по умолчанию все участники члены являются дополнением к группам: тогда как группы показывают группы, к которым принадлежит определенный пользователь, участники показывают пользователей принадлежащих к определенной группе.
... Вы можете попросить первичных участников, второстепенных участников, как на одна строка, каждая на отдельных строках.
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
, если пользователей слишком много.
Привет
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')")
Я пробовал grep 'sample-group-name' /etc/group
, который отобразит список всех членов указанной вами группы на примере здесь
/etc/group
есть как минимум в 3 других ответах, какую ценность ваш ответ добавляет к ним? Кроме того, все остальные ответы содержат комментарии о том, что такое решение работает только для вторичных групп, а также не для учетной записи, управляемой LDAP, NIS и т. Д.
Здесь очень простой 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.
В 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.
Вот 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