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

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

不幸的是,没有一个好的,便携的方法来做到这一点,我知道。 如果你试图parsing/ etc / group,就像其他人所build议的那样,你将会错过那些以该组为主组的用户,以及通过UNIX平面文件以外的机制(如LDAP,NIS, pam-pgsql等)。

如果我绝对必须自己做,我可能会做相反的事情:使用id来获取系统上每个用户的组(这将拉动所有的源对NSS可见),并使用Perl或类似的东西来维护一个发现每个组的哈希表logging该用户的成员资格。

编辑:当然,这留下了一个类似的问题:如何获得系统上的每个用户的列表。 由于我的位置仅使用平面文件和LDAP,因此我只能从两个位置获取列表,但对于您的环境而言可能并非如此。

编辑2:有人提醒我getent passwd会返回系统上的所有用户列表,包括来自LDAP / NIS / etc的所有用户, 但是 getent group依然会遗漏只有通过默认组login的用户,所以这激励我写这个快速的黑客。

 #!/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 group <groupname>; 

它可以跨Linux和Solaris移植,并且可以与本地组/密码文件,NIS和LDAPconfiguration一起使用。

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

使用Python来列出组成员:

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

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

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

 grep <your_group_name> /etc/group 

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

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

以下shell代码片段将遍历所有用户,并仅打印属于给定$group那些用户名。

 getent passwd | while IFS=: read name trash do groups $name | cut -f2 -d: | grep -q -w "$group" && echo $name done 

注意:此解决scheme将检查用户和组的NIS和LDAP(不仅是passwdgroup文件)。 它还会考虑未添加到组的用户,但将组设置为主要组的用户。

编辑:添加修复的罕见的情况下,用户不属于同名的组。

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

 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和tr:

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

Zed的实现应该扩展到其他一些主要的UNIX上。

有人可以访问Solaris或HP-UX硬件? 没有testing这些情况。

 #!/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"; } } 

如果有更好的方法来分享这个build议,请让我知道; 我考虑了很多方法,这就是我想出的。

我做了类似于上面的perl代码,但用原生perl函数replace了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"; 

有一个方便的Debian和Ubuntu软件包叫做' members ',它提供了这个function:

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

…你可以在一条线上寻求主要成员,二级成员,每一个成员都是分开的。

这是一个脚本,它返回来自/ etc / passwd和/ etc / group的用户列表,它不检查NIS或LDAP,但确实显示将该组作为默认组的用户在Debian 4.7和solaris 9上testing

 #!/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 

或者作为一个单线,你可以从这里直接剪切和粘贴(在第一个variables中改变组名)

 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命令。 有关列表用户,请参见Solaris手册页 。

请注意,这个命令是开源Heirloom Project的一部分 。 我认为它在GNU / Linux中是缺less的,因为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的设置中使用了这个function,在任何符合标准的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' 

这有3个部分:

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

2 – awk print只有一行中的成员与','分开。

3 – tr用新行replace',',并连续打印每个用户。

4 – 可选:如果用户太多,也可以使用另一个sortpipe道。

问候