如何列出Linux组中的所有用户?
如何在Linux(可能还有其他Unice)中列出一个组的所有成员?只需一点grep和tr:如何列出Linux组中的所有用户?,linux,unix,Linux,Unix,如何在Linux(可能还有其他Unice)中列出一个组的所有成员?只需一点grep和tr: $ grep ^$GROUP /etc/group | grep -o '[^:]*$' | tr ',' '\n' user1 user2 user3 下面的命令将列出属于的所有用户,但仅列出由/etc/group数据库管理的用户,而不是LDAP、NIS等。它也仅适用于辅助组,它不会列出将该组设置为主组的用户,因为主组存储为GID(数字组ID)在文件/etc/passwd中 awk -F: '/^gr
$ grep ^$GROUP /etc/group | grep -o '[^:]*$' | tr ',' '\n'
user1
user2
user3
下面的命令将列出属于
的所有用户,但仅列出由/etc/group
数据库管理的用户,而不是LDAP、NIS等。它也仅适用于辅助组,它不会列出将该组设置为主组的用户,因为主组存储为GID
(数字组ID)在文件/etc/passwd
中
awk -F: '/^groupname/ {print $4;}' /etc/group
grep <your_group_name> /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";
}
}
getent组;
它可以跨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中的用户和组(不仅是passwd
和group
文件)。它还将考虑未添加到组但将组设置为主组的用户
编辑:为用户不属于同名组的罕见情况添加了修复程序
编辑:以shell脚本的形式编写;添加了
true
以退出,状态为所建议的0
;丢弃的stderr
以跳过那些偶尔出现的组:找不到组ID xxxxxx的名称使用Python列出组成员:
python-c“import grp;print grp.getgrnam('GROUP_NAME')[3]”
请参见以下命令将列出属于
的所有用户,但仅列出由/etc/group
数据库管理的用户,而不是LDAP、NIS等。它也仅适用于辅助组,它不会列出将该组设置为主组的用户,因为主组存储为GID
(数字组ID)在文件/etc/passwd
中
awk -F: '/^groupname/ {print $4;}' /etc/group
grep <your_group_name> /etc/group
grep/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
或者作为一个单行线,您可以直接从这里剪切和粘贴(更改第一个变量中的组名)
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";
}
}
如果有更好的方法分享这个建议,请让我知道;我考虑了很多方法,这就是我的想法。有一个名为“members”的方便的Debian和Ubuntu包,它提供了以下功能:
说明:显示组的成员;默认情况下,所有成员
成员是组的补充:组显示指定用户所属的组,而成员显示用户
属于某一特定群体的
。。。您可以请求主要成员、次要成员,这两种成员都可以在
一行,每行在单独的行上
我所做的与上面的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命令。看
请注意,此命令是开放源代码的一部分。我假设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
,它将根据示例列出您指定的组的所有成员
这将返回一个以空格分隔的用户列表,我在脚本中使用该列表填充数组
for i in $(getent group ftp | awk -F ':' '{print $4}' | sed 's|,| |g')
do
userarray+=("$i")
done
或
这包括3个部分:
1-getent group groupname
显示“/etc/group”文件中的组行。cat/etc/group | grep groupname
的替代方案
2-awk
只打印一行中用“,”分隔的成员
3-tr
用新行替换“的”,并将每个用户打印成一行
4-可选:如果用户太多,也可以使用另一个管道进行排序
关于您可以在单个命令行中执行此操作:
cut -d: -f1,4 /etc/passwd | grep $(getent group <groupname> | cut -d: -f3) | cut -d: -f1
cut-d:-f1,4/etc/passwd | grep$(getent group | cut-d:-f3)| cut-d:-f1
上面的命令列出了将groupname作为主要组的所有用户
如果您还想列出havi的用户
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'
cut -d: -f1,4 /etc/passwd | grep $(getent group <groupname> | cut -d: -f3) | cut -d: -f1
getent group <groupname> | cut -d: -f4 | tr ',' '\n'
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]])"