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

Mel*_*emi 68 user-accounts command-line macos

我试过谷歌搜索,但一无所获。如何列出mygroup从OS X 中的命令行调用的组的所有成员?

$dscl . list /groups将让我所有组...但我怎么能看到每个组的成员?

Arn*_*röm 67

在 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; }; 
Run Code Online (Sandbox Code Playgroud)

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


给有兴趣的人一些解释:

五种不同的方式(我知道)用户可以成为 OS X 中组的成员。该命令不能保证输出所有甚至任何mygroup的成员,因为成员资格也来自用户'主要组 ID、用户UUID的成员资格、从一个组到另一个组的成员资格继承以及由系统计算的成员资格,例如组everyonedscl . -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
Run Code Online (Sandbox Code Playgroud)

补充资料:

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

  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
$ 
Run Code Online (Sandbox Code Playgroud)

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

  • 当我告诉人们,虽然 OS X 表面上大多是美丽的,但在幕后隐藏着一些讨厌的东西时,我想到的就是这种特殊性。 (8认同)

小智 63

您可以使用:

dscacheutil -q group -a name admin
Run Code Online (Sandbox Code Playgroud)

或者:

dscacheutil -q group -a name staff
Run Code Online (Sandbox Code Playgroud)

等等。

  • 不一定完整。`dscacheutil -q group -a name admin` 只给了我 1 个结果,而接受答案的 shell 脚本给了我 2 个结果。 (2认同)
  • 这是不准确的。它并不总是列出所有成员,请参阅下面阿恩的回答 (2认同)

Arn*_*röm 11

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


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

dscl . -read /Groups/mygroup GroupMembership
Run Code Online (Sandbox Code Playgroud)

但这并不能保证输出所有(甚至任何)组成员。缺少的是仅通过将其作为主要组 ID成为组成员的用户。

OS X 中的一个常见示例是常规登录帐户,这些帐户将工作人员(组 20)作为其主要组,但未列在工作人员组的 GroupMembership 属性中。

可以通过搜索数字主要组 ID (gid)来找到这些用户,例如对于员工组 (gid 20):

dscl . -list /Users PrimaryGroupID | grep " 20$"
Run Code Online (Sandbox Code Playgroud)

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

dscl . -read /Groups/mygroup PrimaryGroupID
Run Code Online (Sandbox Code Playgroud)


小智 8

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

id -nG <username>
Run Code Online (Sandbox Code Playgroud)

示例输出:

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
Run Code Online (Sandbox Code Playgroud)

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

操作系统

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

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
Run Code Online (Sandbox Code Playgroud)