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

如何在Linux(可能还有其他unix)中列出一个组的所有成员?

364576 次浏览

再加上grep和tr:

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

下面的命令将列出属于<your_group_name>的所有用户,但只列出由/etc/group数据库管理的用户,而不包括LDAP、NIS等。它也只适用于次要组,它不会列出将该组设置为主组的用户,因为主组存储为文件/etc/passwd中的GID(数字组ID)。

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

不幸的是,据我所知,没有好的、可移植的方法来做到这一点。如果您尝试解析/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";
}
}
lid -g groupname | cut -f1 -d'('
getent group <groupname>;

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

下面的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脚本的形式编写;根据@Max Chernyak,又名hakunin的建议,添加true0状态退出;为了跳过那些偶尔出现的groups: cannot find name for group ID xxxxxx而丢弃stderr

使用Python列出组成员:

import grp;打印grp.getgrnam (GROUP_NAME)[3]”

看到https://docs.python.org/2/library/grp.html

下面的命令将列出属于<your_group_name>的所有用户,但只列出由/etc/group数据库管理的用户,而不包括LDAP、NIS等。它也只适用于次要组,它不会列出将该组设置为主组的用户,因为主组存储为文件/etc/passwd中的GID(数字组ID)。

grep <your_group_name> /etc/group
这是一个返回/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

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

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

有一个方便的Debian和Ubuntu包,名为“成员”,它提供了这个功能:

描述:显示一个组的成员;默认为所有成员 Members是groups的补充:groups表示指定用户所属的组,Members表示用户 属于特定群体的< / p > < p >…你可以请求主要成员,次要成员,都在

我所做的与上面的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";

在UNIX(与GNU/Linux相反)中,有listusers命令。参见Solaris列表用户的手册页

注意,这个命令是开源传家宝项目的一部分。我认为它在GNU/Linux中是缺失的,因为RMS不相信组和权限。: -)

下面是一个非常简单的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 &Awk,包括solaris 8+和hpux。

我已经尝试了grep 'sample-group-name' /etc/group,它将列出基于示例在这里指定的组的所有成员

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')")
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的管道。

问候

你可以在一个命令行中完成:

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'

我认为最简单的方法是以下步骤,你不需要安装任何软件包或软件:

    首先,你要找出你想要知道用户的组的GID,有很多方法: 猫所属(最后一列是GID) Id user(用户是属于组的用户)

  1. 现在,您将在文件/etc/passwd中列出所有用户,但是您将使用以下后续命令应用一些过滤器,以获得前一个组的成员。

cut -d: -f1,4 /etc/passwd |grep GID (GID是你从步骤1中得到的数字)

切命令将选择一些“列”的文件,参数d设置分隔符”:“在这种情况下,参数- f选择“字段”(或列)在案例1和4所示(在/ etc / passwd文件,1º列是用户的名称和4º是用户所属的组的GID),完成| grep GID将滤波器组(4º列),你选择了。

下面是另一个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]])"