Linux 그룹의 모든 사용자를 나열하는 방법은 무엇입니까?


273

Linux에서 그룹의 모든 구성원을 나열하려면 어떻게해야합니까?


1
@ Silmari89, 프로그래밍 방식으로하고 싶지는 않습니다.
Paul Tomblin

2
나는 여기에 새로운 것이 있는데, 질문을 게시 한 직후 SF가 존재한다는 것을 알았습니다. SF 또는 SO에 속한다는 데 동의합니다.
user323094

5
물론 지금은 프로그래밍 방식의 솔루션을 제공하므로 여기에서도 정당화 될 수 있습니다.
Zed

답변:


103

불행히도, 내가 아는 좋은 휴대용 방법은 없습니다. 다른 사람들이 제안한 것처럼 / etc / group을 구문 분석하려고하면 해당 그룹을 기본 그룹으로 사용하는 사용자와 UNIX 플랫 파일 이외의 메커니즘을 통해 해당 그룹에 추가 된 사용자 (예 : LDAP, NIS, pam-pgsql 등).

내가 이것을 직접해야한다면, 아마도 역순으로 할 것입니다 : id시스템의 모든 사용자 그룹을 가져 와서 (NSS에 모든 소스를 표시 할 것입니다) Perl 또는 비슷한 것을 사용하여 해시를 유지하십시오 각 그룹의 테이블은 해당 사용자의 멤버쉽을 발견했습니다.

편집 : 물론 이것은 시스템의 모든 사용자 목록을 얻는 방법과 비슷한 문제가 있습니다. 내 위치는 플랫 파일과 LDAP 만 사용하므로 두 위치 모두에서 목록을 얻을 수 있지만 사용자 환경에 맞지 않을 수도 있습니다.

편집 2 : 전달 중 누군가 getent passwdLDAP / 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";
    }
}

3
답변 해 주신 모든 분들께 감사드립니다. 나는 그것을 할 수있는 휴대용 방법을 찾고있었습니다. 쉽고 휴대하기 쉬운 방법이 없다는 정보가 도움이되었습니다. 또한 문제를 더 깊이 이해하는 데 도움이 된 상황에 대해 가장 자세하게 설명했습니다.
user323094 2016 년

2
스크립트를 Linux 재단에 기부 할 수 있습니까? 2012 년이며 여전히 그룹 회원을 얻는 쉬운 방법은 없습니다. 그것이 리눅스에 대해 저를 좌절시키는 것입니다.
winteck

6
나는 당신을 위해 ISC와 같은 라이센스를 추가했으며, 이는 거의 모든 그룹과 호환됩니다. 수락 될 것 같으면 어디든지 제출하십시오.
Zed

PAM은 계정 정보를 제공하지 않습니다. 그렇게하는 것이 이름 서비스 스위치 (nsswitch)입니다. 모든 '데이터베이스'(데이터 공급자)가 열거를 지원 getent passwd하지는 않으므로 작동하지 않을 수 있습니다 (예 : sssd를 사용하는 경우).

PAM vs NSS에 대한 유효 지점-참조를 변경했습니다. 내가 그것을 사용하지는 않았지만, sssd는 적절한 데이터 공급자가 아니라 언뜻보기에 nscd 교체처럼 보이며, 그것이 깨지면 getent passwdsssd의 버그를 고려할 것입니다.
Zed

239
getent group <groupname>;

Linux 및 Solaris 모두에서 이식 가능하며 로컬 그룹 / 암호 파일, NIS 및 LDAP 구성과 함께 작동합니다.


43
그룹을 기본 그룹으로 사용하는 사용자는 표시하지 않습니다.
rlpowell


39
lid -g groupname | cut -f1 -d'(' 

7
뚜껑이 표준 데비안 설치가 아니라는 점을 제외하면 가장 좋은 방법입니다. 우분투에서는 libuser 옵션 패키지 (동일한 이름을 가진 id-utils의 패키지가 아닙니다)에 있습니다. 데비안에서 찾지 못했습니다 :(
user323094

과학 리눅스에 나를 위해 일한
blong

데비안 Wheezy에서 뚜껑도 libuser 패키지에 있습니다
Lluís

2
@JohnMcGehee RHEL은 AustereLinux라고 불려 졌을 것입니다
goelakash

1
'-g'는 옵션이 아닙니다. 우분투 16.04에 id-utils 버전 4.6이 설치되어 있습니다.
Wilson Biggs

25

다음 명령은에 속하는 모든 사용자를 나열 <your_group_name>하지만 /etc/groupLDAP, NIS 등이 아닌 데이터베이스로 관리되는 사용자 만 나열합니다 . 또한 보조 그룹에 대해서만 작동 하며 기본 그룹이 기본 그룹으로 설정되어 있으므로 해당 그룹을 기본으로 설정 한 사용자는 나열하지 않습니다. GID파일에 (숫자 그룹 ID) 로 저장됩니다 /etc/passwd.

grep <your_group_name> /etc/group

4
grep <username> / etc / group과 같이 해당 파일로 직접 grep 할 수 있습니다. 더 빠르고 적은 오버 헤드.
paintbox

16

다음 명령은에 속하는 모든 사용자를 나열 <your_group_name>하지만 /etc/groupLDAP, NIS 등이 아닌 데이터베이스로 관리되는 사용자 만 나열합니다 . 또한 보조 그룹에 대해서만 작동 하며 기본 그룹이 기본 그룹으로 설정되어 있으므로 해당 그룹을 기본으로 설정 한 사용자는 나열하지 않습니다. GID파일에 (숫자 그룹 ID) 로 저장됩니다 /etc/passwd.

awk -F: '/^groupname/ {print $4;}' /etc/group

7
그룹을 기본 그룹으로 사용하는 사용자는 표시하지 않습니다.
rlpowell

3
NIS 및 LDAP을 확인하지 않습니다.
Paweł Nadolski 2016 년

12

다음 쉘 스크립트는 모든 사용자를 반복하고 지정된 그룹에 속하는 사용자 이름 만 인쇄합니다.

#!/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을 확인합니다이 솔루션 passwdgroup파일). 또한 그룹에 추가되지 않고 그룹이 기본 그룹으로 설정된 사용자를 고려합니다.

편집 : 사용자가 같은 이름을 가진 그룹에 속하지 않는 드문 시나리오에 대한 수정 사항이 추가되었습니다.

편집 : 쉘 스크립트의 형태로 작성; @Max Chernyak aka hakunin이 제안한 상태로 true종료하도록 추가되었습니다 . 가끔 건너 뛰기 위해 버려졌습니다 .0stderrgroups: cannot find name for group ID xxxxxx


이것은 중대하다, 매우 간결하지만 그룹 이름뿐만 아니라 사용자 이름 인쇄
앤드류 로리엔

@andrewlorien, 당신이 언급 한 문제를 해결하기를 바랍니다.
Paweł Nadolski

이 스 니펫은 좋지만 종료 코드 1을 반환합니다. 이유가 0을 반환하지 않는 이유는 무엇입니까? 아마도 쉬운 수정?
Max Chernyak

@hakunin, 마지막 사용자 이름이 그룹에 속하지 않으면 0을 반환하지 않습니다. end 문에 "|| true"를 추가하여 원하는 경우 항상 0을 얻을 수 있습니다. 그런 다음 출력을 확인하여 사용자를 찾았는지 확인할 수 있습니다.
Paweł Nadolski

@ PawełNadolski 내가 깨달았으므로 추가했습니다 ; true. 0을 리턴하면 구성 관리 시스템 (Chef, Ansible 등)이 트립되지 않도록하는 것이 좋습니다.
Max Chernyak

7

단일 명령 줄에서 수행 할 수 있습니다.

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

위의 명령은 그룹 이름 을 기본 그룹으로 사용하는 모든 사용자를 나열합니다.

그룹 이름 을 보조 그룹으로 사용 하는 사용자를 나열 하려면 다음 명령을 사용하십시오.

getent group <groupname> | cut -d: -f4 |  tr ',' '\n'

1
주의 사항 : grep이름에 그룹 번호가 포함 된 사용자와 일치합니다 (예 : 그룹의 sc0tt일부로 표시됨 root). 이것이 문제이면 정규식을 사용하십시오 :$(getent group <groupname> | cut -d: -f3)\$(세미콜론, 그룹 ID 및 행 끝과 일치). (정규 표현식에 따옴표를 추가하거나 bash가 불평하지 마십시오.)
Scott Stevens

@ScottS 합법적 인 함정. 제안 된 단계를 권장합니다
Bhavik

3

약간의 grep과 tr :

$ grep ^$GROUP /etc/group | grep -o '[^:]*$' | tr ',' '\n'
user1
user2
user3

4
그룹을 기본 그룹으로 사용하는 사용자는 표시하지 않습니다.
rlpowell

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

이 제안을 나누는 더 좋은 방법이 있다면 알려주십시오. 나는 여러 가지 방법을 고려했으며 이것이 내가 생각해 낸 것입니다.


확인 변경 한 후 Solaris 10에서 작업 id -Gn/usr/xpg4/bin/id -G -n
user667489

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";

링크 만있는 대답은 스택 오버플로에 대한 좋은 대답으로 간주되지 않습니다. 질문에 대한 답변을 제공하지 않거나이 답변이 허용되는 답변보다 더 나은 방법에 대해 자세히 설명하지 않으므로이를 삭제하십시오. 또는 평판이 충분하면이를 주석으로 추가 할 수 있습니다. 언제든지 자신의 게시물에 댓글을 달 수 있습니다.
Dipen Shah

2

이 기능을 제공하는 ' members ' 라는 편리한 데비안 및 우분투 패키지가 있습니다.

설명 : 그룹의 구성원을 표시합니다. 기본적으로 모든 구성원 구성원은 그룹을 보완합니다. 그룹은 지정된 사용자가 속한 그룹을 표시하고 구성원은 지정된 그룹에 속하는 사용자를 표시합니다.

... 기본 회원, 보조 회원을 모두 한 줄에 각각 별도의 줄에 요청할 수 있습니다.


op가 openwrt를 사용한다면 어떨까요?
user2284570

실제로는 유용하지만 불행히도 도메인 그룹 구성원은보고하지 않습니다.
simlev

1
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

다음은 / 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

0

UNIX (GNU / Linux와 반대)에는 listusers 명령이 있습니다. listusers에 대해서는 Solaris 매뉴얼 페이지를 참조하십시오 .

이 명령은 공개 소스 Heirloom Project의 일부입니다 . RMS는 그룹과 권한을 믿지 않기 때문에 GNU / Linux에서 누락되었다고 가정합니다. :-)


1
이 링크가 질문에 대한 답변을 제공 할 수 있지만 여기에 답변의 필수 부분을 포함시키고 참조 용 링크를 제공하는 것이 좋습니다. 링크 된 페이지가 변경되면 링크 전용 답변이 유효하지 않을 수 있습니다. - 리뷰에서
knuhol

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.
Alun Carr

Heirloom Project 웹 사이트 : Heirloom Project는 표준 Unix 유틸리티의 전통적인 구현을 제공합니다. 많은 경우에, 그들은 Caldera와 Sun에 의해 오픈 소스로 출시 된 오리지널 유닉스 자료에서 파생되었습니다. 인터페이스는 전통적인 관행을 따릅니다. 시간이 지남에 따라 일반적으로 사용되는 확장 기능이 제공되는 경우도 있지만 일반적으로 System V와 호환됩니다. 대부분의 유틸리티는 POSIX 준수를 목표로하는 변형에 포함됩니다.
Alun Carr

0

다음은 다른 답변에 나열된 모든 일반적인 함정을 고려한 매우 간단한 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로 실행됩니다.


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

가장 쉬운 방법은 다음 단계라고 생각하므로 패키지 또는 소프트웨어를 설치할 필요가 없습니다.

  1. 먼저, 사용자를 알고 싶은 그룹의 GID를 찾으십시오. 다음과 같은 방법이 많이 있습니다. cat / etc / group (마지막 열은 GID 임) id user (사용자는 그룹)

  2. 이제 모든 사용자를 / 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º 열) 만 필터링합니다. 선택했다.


0

다음은 사용자의 기본 그룹 멤버십 ( /etc/passwd)과 그룹 데이터베이스 ( /etc/group) 를 고려한 또 다른 Python one-liner입니다.

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]])"

-1

여기grep 'sample-group-name' /etc/group 에 예제를 기반으로 지정한 그룹의 모든 구성원을 나열 하려고 시도 했습니다.


1
Grepping /etc/group은 이미 적어도 3 개의 다른 답변에 있습니다. 귀하의 답변은 어떤 가치를 더합니까? 또한 다른 모든 답변은 이러한 솔루션이 보조 그룹에서만 작동하고 LDAP, NIS 등으로 관리되는 계정에서는 작동하지 않는다는 의견을 가지고 있습니다.
David Ferenczy Rogožan
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.