如何列出Linux组中的所有用户?

时间:2010-05-14 15:28:44

标签: linux unix

如何在Linux(以及可能的其他unices)中列出组中的所有成员?

20 个答案:

答案 0 :(得分:232)

getent group <groupname>;

它可以在Linux和Solaris上移植,并且可以使用本地组/密码文件,NIS和LDAP配置。

答案 1 :(得分:101)

不幸的是,我知道没有好的,可移植的方法来做到这一点。如果您尝试解析/ 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";
    }
}

答案 2 :(得分:39)

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

答案 3 :(得分:39)

使用Python列出组成员:

  

python -c“import grp; print grp.getgrnam('GROUP_NAME')[3]”

请参阅https://docs.python.org/2/library/grp.html

答案 4 :(得分:25)

以下命令将列出属于<your_group_name>的所有用户,但仅列出/etc/group数据库管理的用户,而不是LDAP,NIS等。仅适用于辅助组,它不会列出将该组设置为主要组的用户,因为主要组在文件GID中存储为/etc/passwd(数字组ID)。

grep <your_group_name> /etc/group

答案 5 :(得分:16)

以下命令将列出属于<your_group_name>的所有用户,但仅列出/etc/group数据库管理的用户,而不是LDAP,NIS等。仅适用于辅助组,它不会列出将该组设置为主要组的用户,因为主要组在文件GID中存储为/etc/passwd(数字组ID)。

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

答案 6 :(得分:12)

以下shell脚本将遍历所有用户并仅打印属于给定组的用户名:

#!/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文件。它还会考虑未添加到组但将组设置为主要组的用户。

编辑:针对用户不属于同名群组的罕见情况添加了修补程序。

编辑:以shell脚本的形式编写;已添加true@Max Chernyak aka hakunin的建议退出0状态;丢弃stderr以便跳过偶然的groups: cannot find name for group ID xxxxxx

答案 7 :(得分:6)

您可以在一个命令行中执行此操作:

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'

答案 8 :(得分: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";
    }
}

如果有更好的方式来分享这个建议,请告诉我;我考虑了很多方法,这就是我提出的方法。

答案 9 :(得分:3)

我这样做与上面的perl代码类似,但用本机perl函数替换了getent和id。它更快,应该适用于不同的* 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";

答案 10 :(得分:2)

有一个名为“成员”的方便的Debian和Ubuntu软件包提供此功能:

  

描述:显示组的成员;默认情况下,所有成员    成员是组的补充:组显示指定用户所属的组,成员显示用户    属于指定的组。

     

...你可以要求主要成员,次要成员    一行,每行分开。

答案 11 :(得分:2)

只是一点点grep和tr:

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

答案 12 :(得分: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')")

答案 13 :(得分:0)

在UNIX(与GNU / Linux相对)中,有listusers命令。请参阅Solaris man page for listusers

请注意,此命令是开源Heirloom Project的一部分。我认为它在GNU / Linux中缺失,因为RMS不相信组和权限。 : - )

答案 14 :(得分: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的设置中使用它,可以运行任何符合标准的getent&amp; awk,包括solaris 8+和hpux。

答案 15 :(得分:0)

getent group groupname | awk -F: '{print $4}' | tr , '\n'

这有三个部分:

1 - getent group groupname显示“/ etc / group”文件中组的行。替代cat /etc/group | grep groupname

2 - awk打印只有一行中的成员与','分开。

3 - tr用新行代替','并连续打印每个用户。

4 - 可选:如果用户太多,您还可以使用另一个sort管道。

此致

答案 16 :(得分:0)

这是一个脚本,它返回/ 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

答案 17 :(得分:0)

我认为最简单的方法是执行以下步骤,您无需安装任何软件包或软件:

  1. 首先,找到您想了解用户的组的GID,有很多方法可以实现: cat / etc / group (最后一列是GID) id用户(该用户是属于该组的人)

  2. 现在,您将在/ etc / passwd文件中列出所有用户,但是您将应用带有以下命令序列的一些过滤器,以仅获取上一组的成员。

剪切-d:-f1,4 / etc / passwd | grep GID (GID是您从第1步中获得的数字)

cut命令将仅选择文件的某些“列”,在这种情况下,参数d设置定界符“:”,参数-f选择要显示为1和4的“字段”(或列)情况(在文件/ etc / passwd上,1º列是用户名,4º是用户所属组的GID),最后确定| grep GID将仅过滤该组(在4º列上) )您选择的。

答案 18 :(得分:0)

这是另一个Python单行代码,它考虑了用户的默认组成员身份(来自/etc/passwd)和组数据库(/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]])"

答案 19 :(得分:-1)

我已尝试grep 'sample-group-name' /etc/group,它会根据示例here列出您指定的论坛的所有成员