如何列出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]”
以下命令将列出属于<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(不仅是passwd
和group
文件)。 它还会考虑未添加到组的用户,但将组设置为主要组的用户。
编辑:添加修复的罕见的情况下,用户不属于同名的组。
你可以在一个命令行中完成:
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 – 可选:如果用户太多,也可以使用另一个sort
pipe道。
问候