グループのすべてのメンバーをリストする(Mac OS X)


56

私はグーグルを試しましたが、どこにも行きません。OS Xのコマンドラインmygroupから呼び出されたグループのすべてのメンバーを一覧表示するにはどうすればよいですか?

$ dscl . list /groupsはすべてのグループを取得します...しかし、どのように各グループのメンバーを見ることができますか?

回答:


40

次を使用できます。

dscacheutil -q group -a name admin

または:

dscacheutil -q group -a name staff


これは私のお気に入りの方法です。簡単で簡単、正確。ありがとう!
TryTryAgain

使用例の90%はこれで解決でき、回答として投稿されたより複雑なスクリプトでは解決できないため、これは素晴らしい回答です。
JakeGould

これをシェルスタートアップファイルのエイリアスとして追加するだけで、1語のコマンドにグループ名を追加できます。
ニールモンロー

「dscacheutil -q group」を試してみたところ、グループ「admin」の2つの段落がありました。この2つの名前は同じgidですが、ユーザーリストは異なります。何か案が?どうも!
ゴールデンサム

必ずしも完全ではありません。dscacheutil -q group -a name adminAccepted Answerのシェルスクリプトでは2つの結果が得られましたが、1つの結果しか得られませんでした。
ウィスバッキー

64

OS Xにはグループのすべてのメンバーをリストする標準コマンドはないため、これを行うシェル関数を次に示します。

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


興味のある人への説明:

ある5種類の方法は、(私の知っていること)、ユーザはコマンドがOS Xのグループのメンバーになることができていることの、すべて、あるいは任意の出力には保証されませんMYGROUPメンバーシップは、ユーザーから来ているので、s「のメンバーは、 ' プライマリグループID、ユーザーのUUIDによるメンバーシップ、あるグループから別のグループへのメンバーシップの継承、およびグループEveryoneなどのシステムによって計算されるメンバーシップ。dscl . -read /Groups/mygroup GroupMembership

したがって、これらすべてを追跡しようとするのではなく、システム上のすべてのユーザーのメンバーシップを(dsmemberutilを使用して)単純に確認することをお勧めします。これがシェル関数と以下のスクリプトの機能です。


このメンバースクリプトはシェル関数と同等ですが、無効な入力をより適切に処理します。

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

補足情報:

グループメンバーになるには、次の5つの方法があります。

  1. ユーザーのPrimaryGroupID
  2. グループのGroupMembershipにリストされています
  3. グループのGroupMembersにリストされているUUID
  4. グループXのNestedGroupsにリストされているグループYのメンバーであることによるグループXの継承メンバーシップ
  5. システムによって計算されたメンバーシップ

これらは次のようなコマンドで調べることができます dscl . -read /Groups/somegroup

4の例:印刷オペレーターグループ__lpoperator_のメンバーシップは、印刷管理者グループ__lpadmin_のメンバーに継承され、そのグループのメンバーシップは管理グループのメンバーに継承されます。

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が表面的にはほとんど美しいのに、カバーの下にいくつかの厄介なものが隠されていると人々に話すとき、私が念頭に置いている一種の特性です。
ステファンシュミット

+1:これは確実に機能します。メルシー。
スリップD.トンプソン

これは、管理グループから自分自身を削除する方法を見つけるために必要な情報です。ユーザー名による削除では不十分であることが判明しました。UUIDも削除する必要があります。github.com/ drduh / macOS
Jens Timmerman

10

注:これは私が実現する前に書かれた私の最初の答えだった。この答えはまだ不完全な結果を与えます。(たとえば、 everyone グループのメンバーは見つかりません!)そこで、より良い答えを書きました。これには、OS Xのグループのすべてのメンバーをリストするスクリプトが含まれています


mygroupのGroupMembershipプロパティは、次のようにdsclで出力できます。

dscl . -read /Groups/mygroup GroupMembership

ただし、これは、グループのすべてのメンバー(または任意のメンバー)を出力することを保証するものではありません。不足しているのは、プライマリグループIDとしてのみグループのメンバーであるユーザーです。

OS Xでのこの一般的な例は、プライマリグループとしてスタッフ(グループ20)がいるが、スタッフグループのGroupMembershipプロパティにはリストされていない通常のログインアカウントです。

これらのユーザーは、スタッフグループ(gid 20)の次の例のように、数値のプライマリグループID(gid)を検索することで見つけることができます。

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これはまさに私が望んでいたことです。ここで「ユーザーのすべてのグループを一覧表示」を探しました。これを明確にするために編集を提案します
アイザック

4

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

注意:上記のコマンドは、すべてのグループメンバーの完全なリストを常に表示するとは限りません。たとえば、グループ「スタッフ」の場合、不完全なグループメンバーとして「ルート」のみを取得します。それはデフォルトのユーザー(NOT「ルート」)として、次のいずれかのコマンドを使用して確認するには:id -GnORgroups

その結果、デフォルトのログインユーザーがメンバーになっているすべてのグループが表示されます。それらの1つは「スタッフ」でなければなりません。したがって、「root」の他に、グループ「staff」のメンバーがさらに存在しますが、それらはコマンドではリストされませんdscl . -read /Groups/[groupname] | grep GroupMembership。同じことは、dscacheutil -q group -a name staff「ルート」のみが「スタッフ」グループのメンバーであることを示唆するコマンドにも当てはまりますが、これは明らかに不完全です。

OSXのターミナルで実際にグループのすべてのメンバーを取得する唯一の信頼できる方法は、すでにArneStenströmによって提供されています。これは彼のシェル関数を使用しています。彼のシェルスクリプト。両方ともうまくいきます!


1

コマンド

@duperuserの答えと同様に、次のコードはグループのユーザーのみを印刷しadmin、間にスペースを入れます:

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

出力

上記のコマンドを実行すると、次のようなものが生成されます。

root your_username someone_else

壊す

このdscacheutilコマンドは、システムのディレクトリサービスキャッシュのさまざまなカテゴリに関する情報を照会するために使用されます。この-qオプションを使用すると、クエリするカテゴリを指定できます。利用可能なカテゴリは、グループ、ホスト、マウント、プロトコル、rpc、サービス、およびユーザーです。-aオプションでキーと値のペアを指定することにより、そのカテゴリをさらにクエリします。この場合、namevalueと等しいキーを持つグループをリストしますadmin。上記のdscacheutilコマンドは、次のような出力を生成します。

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

次に、このテキストをパイプして、先頭にgrep文字列users:を含む行を選択します。この-eオプションにより、grepは正規表現を認識します。^私たちが望む文字を指定users:行の先頭にあることを。

これは私たちに与えます

users: root yourusername

最後に、これをsedに渡し、テキストusers:を空の文字列に置き換えます。ではsedは、最初の文字のs意味は、置換します。最初のスラッシュのペア(/users: /)の間のテキストは置換したいものであり、次のスラッシュのペア(//)は置換したいものです(この場合は何もありません)。


0

これは関連する議論の実装からられたこの問題の実装です。 このルーチンはやや汎用的で、特定のプラットフォーム/アーキテクチャ用のディレクトリサービスルックアップフックがあるため、異種ネットワーク上で変更せずに使用できます。 このユーティリティへのシンボリックリンクをインストールしました。この実装の他の起源は、スクリプトの属性セクションに記載されています。このツールは、少なくともOSX、HP-UX、Linux、およびSunOSで実行することを目的としていますが、まだ実行されていません。zedSunOSおよびHP-UXでテスト済み。スクリプトは、Ubuntu Linux 12.04およびMavericks OSX 10.9.1で可能な限りテストされました。このスクリプトの出力は、この問題の最初のシェルスクリプト実装の出力と一致するため、正しいと見なされます。

#!/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";
    }
}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.