列出组中的所有成员(Mac OS X)


56

我尝试了谷歌搜索,但没有到达任何地方。如何列出一个名为组的所有成员mygroup命令行中的OS X?

$ dscl . list /groups将使我成为所有组的成员...但是如何查看每个组的成员?

Answers:


40

您可以使用:

dscacheutil -q group -a name admin

要么:

dscacheutil -q group -a name staff

等等


这是我最喜欢的方法。简单易行,准确无误。谢谢!
TryTryAgain

这是一个很好的答案,因为90%的用例可以通过此方法解决,而不是通过作为答案发布的更复杂的脚本来解决。
JakeGould 2015年

只要将此作为别名添加到您的Shell启动文件中,就可以使它成为一个单词的命令加上组名。
尼尔·梦露

当我尝试“ dscacheutil -q组”时,我得到了“ admin”组的2个段落。两者具有相同的名称,gid,但用户列表不同。任何想法?谢谢!
Golden Thumb

不一定完整。dscacheutil -q group -a name admin只给了我1个结果,而Accepted Answer的shell脚本给了我2个结果。
Wisbucky

64

没有标准命令列出OS X中某个组的所有成员,因此这是一个执行此操作的Shell函数:

members () { dscl . -list /Users | while read user; do printf "$user "; dsmemberutil checkmembership -U "$user" -G "$*"; done | grep "is a member" | cut -d " " -f 1; }; 

将上面的命令行复制到终端,然后键入(其中mygroup是现有组的名称)。members mygroup


对那些感兴趣的人的一些解释:

(我知道)有五种不同的方法可以使用户成为OS X中组的成员。不能保证该命令输出mygroup的全部或什至任何成员,因为成员资格也来自用户。 “ 主要组ID,由用户的成员资格UUID由系统计算的,如组,会员的继承从一个组至另一个,和成员大家dscl . -read /Groups/mygroup GroupMembership

因此,与其尝试跟踪所有这些,不如简单地检查系统上每个用户的成员资格(使用dsmemberutil),这是一个更好的主意,这就是下面的shell函数和脚本所要做的。


成员脚本等效于shell函数,但是对无效输入的处理更好:

#!/bin/bash

# members -- list all members of a group
#
# SYNOPSIS
#   members groupname
#
# http://superuser.com/questions/279891/list-all-members-of-a-group-mac-os-x
#  by Arne
# Expected to work on Mac OS 10.5 and newer, tested on 10.6 and 10.7.
# It could be rewritten to work on 10.4 by using "dseditgroup -o checkmember"
# instead of "dsmemberutil checkmembership".
# By using dseditgroup, the script could also be extended to handle
# other Directory Service nodes than the default local node.
#

the_group="$1"
# Input check and usage
  if [[ $# != 1 || $1 == -* || $1 =~ [[:space:]] ]]; then
    echo "Usage: ${0##*/} groupname" >&2
    echo "Lists all members of the group." >&2
    exit 64
  elif (dsmemberutil checkmembership -U root -G "$the_group" 2>&1 \
    | grep "group .* cannot be found") >&2; then
    exit 1
  fi

# Check every user
exec dscl . -list /Users \
  | while read each_username
  do
    printf "$each_username "
    dsmemberutil checkmembership -U "$each_username" -G "$the_group"
  done \
    | grep "is a member" | cut -d " " -f 1

# eof

补充信息:

成为小组成员的五种方式是:

  1. 用户的PrimaryGroupID
  2. 列在该组的GroupMembership中
  3. 该组的GroupMembers中列出的UUID
  4. 通过成为组X的NestedGroups中列出的组Y的成员继承了组X的成员身份
  5. 系统计算的会员资格

可以使用以下命令探索这些 dscl . -read /Groups/somegroup

4的示例:打印操作员组__lpoperator_的成员资格由打印管理员组__lpadmin_的成员继承,而该组的成员资格由admin组的成员继承。

示例5

$ dscl . -read /Groups/netaccounts Comment
Comment:
 Group membership calculated by system
 Accounts from a remote directory server
$ 

另请参见
    id(1)dscl(1)dsmemberutil(1)dseditgroup(8)DirectoryServiceAttributes(7)uuid(3)


7
当我告诉人们OS X表面上最漂亮的时候,我想到的就是这种特殊性,但它们的掩盖之下却隐藏着一些讨厌的东西。
Stefan Schmidt'5

+1:这很可靠。谢谢
Slipp D. Thompson

这是我需要弄清楚如何从管理组中删除自己的信息。原来的用户名删除是不是足够多,你还需要删除的UUID,看到github.com/drduh/macOS-Security-and-Privacy-Guide/issues/...
延斯·蒂默曼

10

注意:这是我最初的答案,写于我意识到这个答案仍然给出不完整的结果之前。(例如,它找不到所有人组中的成员!)因此,我写了一个更好的答案,其中包括一个脚本,该脚本列出了OS X中组中的所有成员


可以使用dscl打印mygroup的GroupMembership属性,如下所示:

dscl . -read /Groups/mygroup GroupMembership

但这不能保证输出组的所有(或什至任何)成员。仅通过将组作为其主要组ID来丢失属于该组成员的用户。

在OS X中,一个常见的示例是常规登录帐户,该帐户以人员(组20)为主要组,但未在人员组的GroupMembership属性中列出。

可以通过搜索数字主组ID(gid)来找到这些用户,例如本示例中的人员组(gid 20):

dscl . -list /Users PrimaryGroupID | grep " 20$"

通过以下方式找到mygroup的数字gid(PrimaryGroupID):

dscl . -read /Groups/mygroup PrimaryGroupID

7

要获取用户所在的所有组,可以使用以下命令:

id -nG <username>

示例输出:

staff com.apple.sharepoint.group.1 everyone localaccounts _appserverusr admin _appserveradm _lpadmin _appstore _lpoperator _developer com.apple.access_ftp com.apple.access_screensharing com.apple.access_ssh

使用上面的命令,可以获取属于一个组的所有用户

OSX

group=staff;
for i in $(dscl . list /users);
do [[ $(id -nG $i | grep $group) ]] && echo $i;
done

Unix

group=sudo;
# This only outputs lines that match a username (from the start of line to a colon must not be a hash indicating a comment) 
for i in $(grep -oE "^[^#:]+" /etc/passwd);
do [[ $(id -nG $i | grep $group) ]] && echo $i;
done

这是获取用户所属组列表的不错的技巧。但这与OP提出的要求相反,后者是属于一个组的用户列表。
Wisbucky

@wisbucky这正是我所追求的。我在这里寻找“列出用户的所有组”。我将建议您进行修改以澄清这一点
Isaac

4

dscl . -read /Groups/[groupname] | grep GroupMembership

注意:上面的命令并不总是显示所有组成员的完整列表。例如,对于“ staff”组,您只能以“ root”作为不完整的组成员。要检查它,请使用以下命令之一作为默认用户(不是“ root”):id -Gngroups

结果,您将看到默认登录用户所属的所有组。其中之一应该是“职员”。因此,除“ root”用户外,还有“ staff”组的更多成员,这些成员未在命令中列出dscl . -read /Groups/[groupname] | grep GroupMembership。该命令dscacheutil -q group -a name staff也是如此,它还建议您只有“ root”是“ staff”组的成员,这显然是不完整的。

ArneStenström已经提供了在OSX终端上获取组中所有成员的唯一可靠方法。这是使用他的shell函数resp。他的shell脚本。两者都很好!


1

命令

与@duperuser的答案类似,以下内容将仅打印出该组的用户,admin并在两者之间留有空格:

dscacheutil -q group -a name admin | grep -e '^users:' | sed 's/users: //'

输出量

运行上面的命令将产生如下内容:

root your_username someone_else

分解

dscacheutil命令用于查询有关系统目录服务缓存的各种类别的信息。该-q选项使您可以指定要查询的类别。可用类别为组,主机,安装,协议,rpc,服务和用户。我们通过使用-a选项指定键值对来进一步查询该类别。在这种情况下,我们要列出密钥name等于value的组admindscacheutil上面的命令产生如下输出:

name: admin
password: *
gid: 80
users: root yourusername

接下来,我们将该文本输入管道,grepusers:在开头选择包含字符串的行。该-e选项使grep可以识别正则表达式。该^字符指定我们希望users:是在该行的开头。

这给了我们

users: root yourusername

最后,我们将其传递给sed并将文本替换users:为空字符串。在sed中,首字母s表示替代。/users: /我们要替换第一对斜杠()之间的文本,而我们要替换第二对斜杠(//)(在这种情况下,什么也没有)。


0

这是此问题的一种实现,该实现是从相关讨论中的实现衍生而来的。 该例程有点通用,带有针对任何特定平台/体系结构的目录服务查找挂钩,因此可以在不修改异构网络的情况下使用它。 我们已经安装了指向名为的实用程序的符号链接。脚本的归属部分中提到了此实现的其他来源。该工具旨在至少在OSX,HP-UX,Linux和SunOS上运行,但尚未zed在SunOS和HP-UX上进行了测试。该脚本已在Ubuntu Linux 12.04和Mavericks OSX 10.9.1上进行了尽可能的测试。该脚本的输出与该问题的第一个Shell脚本实现的输出匹配,因此被认为是正确的。

#!/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";
    }
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.