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 "import grp; print grp.getgrnam ( 'GROUP_NAME') [3]"
lid -g groupname | cut -f1 -d'('
다음 명령은에 속하는 모든 사용자를 나열 <your_group_name>
하지만 /etc/group
LDAP, NIS 등이 아닌 데이터베이스로 관리되는 사용자 만 나열합니다 . 또한 보조 그룹에 대해서만 작동 하며 기본 그룹이 기본 그룹으로 설정되어 있으므로 해당 그룹을 기본으로 설정 한 사용자는 나열하지 않습니다. GID
파일에 (숫자 그룹 ID) 로 저장됩니다 /etc/passwd
.
grep <your_group_name> /etc/group
다음 명령은에 속하는 모든 사용자를 나열 <your_group_name>
하지만 /etc/group
LDAP, NIS 등이 아닌 데이터베이스로 관리되는 사용자 만 나열합니다 . 또한 보조 그룹에 대해서만 작동 하며 기본 그룹이 기본 그룹으로 설정되어 있으므로 해당 그룹을 기본으로 설정 한 사용자는 나열하지 않습니다. GID
파일에 (숫자 그룹 ID) 로 저장됩니다 /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
파일). 또한 그룹에 추가되지 않고 그룹이 기본 그룹으로 설정된 사용자를 고려합니다.
편집 : 사용자가 같은 이름을 가진 그룹에 속하지 않는 드문 시나리오에 대한 수정 사항이 추가되었습니다.
편집 : 쉘 스크립트의 형태로 작성; @Max Chernyak aka hakunin이 제안한 상태로 true
종료하도록 추가되었습니다 . 가끔 건너 뛰기 위해 버려졌습니다 .0
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)\$
(세미콜론, 그룹 ID 및 행 끝과 일치). (정규 표현식에 따옴표를 추가하거나 bash가 불평하지 마십시오.)
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";
이 기능을 제공하는 ' 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을 확인하지 않지만 그룹을 기본 그룹으로 가지고있는 사용자를 데비안 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 명령이 있습니다. listusers에 대해서는 Solaris 매뉴얼 페이지를 참조하십시오 .
이 명령은 공개 소스 Heirloom Project의 일부입니다 . RMS는 그룹과 권한을 믿지 않기 때문에 GNU / Linux에서 누락되었다고 가정합니다. :-)
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 지원 설정과 함께 이것을 사용하고 있으며 solaris 8 이상 및 hpux를 포함하여 표준 호환 getent & awk로 실행됩니다.
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º 열) 만 필터링합니다. 선택했다.
/etc/group
은 이미 적어도 3 개의 다른 답변에 있습니다. 귀하의 답변은 어떤 가치를 더합니까? 또한 다른 모든 답변은 이러한 솔루션이 보조 그룹에서만 작동하고 LDAP, NIS 등으로 관리되는 계정에서는 작동하지 않는다는 의견을 가지고 있습니다.