Jak wyświetlić listę wszystkich członków grupy w systemie Linux (i ewentualnie innych jednorożców)?
Jak wyświetlić listę wszystkich członków grupy w systemie Linux (i ewentualnie innych jednorożców)?
Odpowiedzi:
Niestety, nie ma dobrego, przenośnego sposobu na zrobienie tego, o czym wiem. Jeśli spróbujesz parsować plik / etc / group, jak sugerują inni, przegapisz użytkowników, którzy mają tę grupę jako grupę podstawową, oraz każdego, kto został dodany do tej grupy za pomocą mechanizmu innego niż pliki płaskie UNIX (tj. LDAP, NIS, pam-pgsql itp.).
Gdybym absolutnie musiał to zrobić sam, prawdopodobnie zrobiłbym to w odwrotnym kierunku: użyj, id
aby uzyskać grupy każdego użytkownika w systemie (który ściągnie wszystkie źródła widoczne dla NSS), i użyj Perla lub czegoś podobnego do utrzymania skrótu tabela dla każdej wykrytej grupy z podaniem członkostwa tego użytkownika.
Edycja: Oczywiście pozostawia to podobny problem: jak uzyskać listę każdego użytkownika w systemie. Ponieważ moja lokalizacja używa tylko płaskich plików i LDAP, mogę po prostu uzyskać listę z obu lokalizacji, ale może to być prawda lub nie dla twojego środowiska.
Edycja 2: Ktoś przechodzący przypomniał mi, że getent passwd
zwróci listę wszystkich użytkowników w systemie, w tym użytkowników z LDAP / NIS / itp., Ale getent group
nadal będzie tęsknił za użytkownikami będącymi członkami tylko poprzez domyślny wpis grupy, więc zainspirowało mnie to do napisz ten szybki hack.
#!/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
mogą nie działać (jeśli na przykład używasz sssd).
getent passwd
, uznałbym to za błąd w sssd.
Użyj Pythona, aby wyświetlić członków grupy:
python -c "import grp; print grp.getgrnam ('GROUP_NAME') [3]"
lid -g groupname | cut -f1 -d'('
Następujące polecenie wyświetli listę wszystkich użytkowników należących do <your_group_name>
, ale tylko tych zarządzanych przez /etc/group
bazę danych, a nie LDAP, NIS itp. Działa również tylko dla grup drugorzędnych , nie wyświetli listy użytkowników, dla których ta grupa jest ustawiona jako podstawowa, ponieważ grupa podstawowa to przechowywane jako GID
(numeryczny identyfikator grupy) w pliku /etc/passwd
.
grep <your_group_name> /etc/group
Następujące polecenie wyświetli listę wszystkich użytkowników należących do <your_group_name>
, ale tylko tych zarządzanych przez /etc/group
bazę danych, a nie LDAP, NIS itp. Działa również tylko dla grup drugorzędnych , nie wyświetli listy użytkowników, dla których ta grupa jest ustawiona jako podstawowa, ponieważ grupa podstawowa to przechowywane jako GID
(numeryczny identyfikator grupy) w pliku /etc/passwd
.
awk -F: '/^groupname/ {print $4;}' /etc/group
Poniższy skrypt powłoki wykona iterację przez wszystkich użytkowników i wydrukuje tylko te nazwy użytkowników, które należą do danej grupy:
#!/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
Przykład użycia:
./script 'DOMAIN+Group Name'
Uwaga: To rozwiązanie sprawdzi NIS i LDAP dla użytkowników i grup (nie tylko passwd
i group
pliki). Uwzględnia również użytkowników, którzy nie zostali dodani do grupy, ale ustawili ją jako grupę podstawową.
Edycja: Dodano poprawkę do rzadkiego scenariusza, w którym użytkownik nie należy do grupy o tej samej nazwie.
Edycja: napisane w formie skryptu powłoki; dodano, true
aby wyjść ze 0
statusem sugerowanym przez @Max Chernyak aka hakunin ; odrzucane stderr
, aby czasami je pominąć groups: cannot find name for group ID xxxxxx
.
; true
. Zwrócenie 0 jest dobre, aby uniknąć wyzwolenia systemu zarządzania konfiguracją (Chef, Ansible itp.).
Możesz to zrobić w jednym wierszu poleceń:
cut -d: -f1,4 /etc/passwd | grep $(getent group <groupname> | cut -d: -f3) | cut -d: -f1
Powyższe polecenie wyświetla listę wszystkich użytkowników, których nazwa grupy jest grupą podstawową
Jeśli chcesz również wymienić użytkowników mających nazwę grupy jako grupę drugorzędną, użyj następującego polecenia
getent group <groupname> | cut -d: -f4 | tr ',' '\n'
grep
dopasuje użytkownika, którego nazwa zawiera numer grupy (np. sc0tt
Będzie wyświetlana jako część root
grupy). Jeśli jest to problem, użyj wyrażenia regularnego :$(getent group <groupname> | cut -d: -f3)\$
(pasuje do średnika, identyfikatora grupy i końca linii). (Nie dodawaj cudzysłowów do wyrażenia regularnego, ani bash narzeka.)
Implementacja Zeda powinna prawdopodobnie zostać rozszerzona na niektóre inne ważne systemy UNIX.
Czy ktoś ma dostęp do sprzętu Solaris lub HP-UX ?; nie testowałem tych przypadków.
#!/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";
}
}
Jeśli istnieje lepszy sposób podzielenia się tą sugestią, daj mi znać; Rozważyłem wiele sposobów i właśnie to wymyśliłem.
id -Gn
na/usr/xpg4/bin/id -G -n
Zrobiłem to podobnie do powyższego kodu perla, ale zastąpiłem getent i id natywnymi funkcjami perla. Jest o wiele szybszy i powinien działać w różnych smakach * 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";
Istnieje przydatny pakiet Debian i Ubuntu o nazwie „ członkowie ”, który zapewnia tę funkcjonalność:
Opis: pokazuje członków grupy; domyślnie wszyscy członkowie są uzupełnieniem grup: podczas gdy grupy pokazują grupy, do których należy określony użytkownik, członkowie pokazują użytkowników należących do określonej grupy.
... Możesz poprosić o członków pierwotnych, członków drugorzędnych, oba w jednym wierszu, każdy w osobnych wierszach.
getent group insert_group_name_here | awk -F ':' '{print $4}' | sed 's|,| |g'
Zwraca rozdzieloną spacjami listę użytkowników, których użyłem w skryptach do zapełniania tablic.
for i in $(getent group ftp | awk -F ':' '{print $4}' | sed 's|,| |g')
do
userarray+=("$i")
done
lub
userarray+=("$(getent group GROUPNAME | awk -F ':' '{print $4}' | sed 's|,| |g')")
Oto skrypt, który zwraca listę użytkowników z / etc / passwd i / etc / group, nie sprawdza NIS ani LDAP, ale pokazuje użytkowników, którzy mają grupę jako grupę domyślną Testowane na Debianie 4.7 i 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
lub jako linijka możesz wycinać i wklejać stąd (zmień nazwę grupy w pierwszej zmiennej)
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
W UNIX (w przeciwieństwie do GNU / Linux) dostępna jest komenda listusers. Listusers można znaleźć na stronie podręcznika Solaris .
Zauważ, że to polecenie jest częścią projektu Heirloom Open Source . Zakładam, że brakuje go w GNU / Linux, ponieważ RMS nie wierzy w grupy i uprawnienia. :-)
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.
Oto bardzo prosty skrypt awk, który uwzględnia wszystkie typowe pułapki wymienione w innych odpowiedziach:
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}'
Używam tego z moją konfiguracją z obsługą ldap, działa na każdym sprzęcie zgodnym ze standardami getent & awk, w tym Solaris 8+ i HPux.
getent group groupname | awk -F: '{print $4}' | tr , '\n'
Składa się z 3 części:
1 - getent group groupname
pokazuje linię grupy w pliku „/ etc / group”. Alternatywa dla cat /etc/group | grep groupname
.
2 - awk
print to tylko elementy w jednym wierszu z oddzielnym „,”.
3 - tr
zamień „,” na nowy wiersz i wypisz każdego użytkownika z rzędu.
4 - Opcjonalnie: Możesz również użyć innej rury sort
, jeśli użytkowników jest zbyt wielu.
pozdrowienia
Myślę, że najprostszym sposobem są następujące kroki, nie trzeba instalować żadnego pakietu ani oprogramowania:
Najpierw dowiadujesz się o GID grupy, którą chcesz znać użytkowników, jest na to wiele sposobów: cat / etc / group (ostatnia kolumna to GID) id użytkownik (użytkownik to ktoś, kto należy do Grupa)
Teraz wyświetlisz listę wszystkich użytkowników w pliku / etc / passwd, ale zastosujesz niektóre filtry z następującą sekwencją poleceń, aby uzyskać tylko członków poprzedniej grupy.
cut -d: -f1,4 / etc / passwd | grep GID (GID to liczba uzyskana z kroku 1)
polecenie cut wybierze tylko niektóre „kolumny” pliku, parametr d ustawia ogranicznik „:” w tym przypadku parametr -f wybiera „pola” (lub kolumny), które mają być pokazane 1 i 4 w przypadku (na plik / etc / passwd, kolumna 1º to nazwa użytkownika, a 4º to GID grupy, do której należy użytkownik), aby sfinalizować GID | grep filtruje tylko grupę (w kolumnie 4º), którą wybrał.
Oto kolejna linijka Pythona, która uwzględnia domyślne członkostwo użytkownika w grupie (od /etc/passwd
), a także z bazy danych grupy ( /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]])"
Próbowałem grep 'sample-group-name' /etc/group
, aby wyświetlić listę wszystkich członków grupy, którą określiłeś na podstawie przykładu tutaj
/etc/group
jest już w co najmniej 3 innych odpowiedziach, jaką wartość dodaje do nich twoja odpowiedź? Ponadto wszystkie pozostałe odpowiedzi mają komentarze, że takie rozwiązanie działa tylko dla grup drugorzędnych, a także nie działa dla konta zarządzanego przez LDAP, NIS itp.