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

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

편집 : 쉘 스크립트의 형태로 작성; @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.