Daftar semua anggota grup (Mac OS X)

56

Saya sudah mencoba Googling tetapi tidak berhasil. Bagaimana saya bisa mendaftar semua anggota grup yang dipanggil mygroupdari baris perintah di OS X?

$ dscl . list /groupsakan mendapatkan saya semua grup ... tetapi bagaimana saya bisa melihat anggota masing-masing grup?

Meltemi
sumber

Jawaban:

40

Anda dapat gunakan:

dscacheutil -q group -a name admin

atau:

dscacheutil -q group -a name staff

dll.

duperuser
sumber
Ini adalah metode favorit saya. Peasy mudah, dan akurat. Terima kasih!
TryTryAgain
Ini adalah jawaban yang bagus karena 90% dari kasus penggunaan dapat diselesaikan dengan ini dan tidak dengan skrip yang lebih rumit yang telah diposting sebagai jawaban.
JakeGould
Cukup tambahkan ini sebagai alias di file startup shell Anda dan Anda bisa menjadikannya perintah satu kata plus nama grup.
Neil Monroe
Ketika saya mencoba "dscacheutil -q group", saya mendapat 2 paragraf untuk grup "admin". Keduanya memiliki nama yang sama, gid, tetapi daftar pengguna yang berbeda. Ada ide? Terima kasih!
Golden Thumb
Belum tentu lengkap. dscacheutil -q group -a name adminhanya memberi saya 1 hasil, sedangkan skrip shell diterima Penerima memberi saya 2 hasil.
wisbucky
64

Tidak ada perintah standar yang mencantumkan semua anggota grup di OS X, jadi inilah fungsi shell yang melakukan itu:

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

Salin baris perintah di atas ke Terminal, lalu ketik (di mana mygroup adalah nama grup yang ada).members mygroup


Beberapa penjelasan untuk mereka yang tertarik:

Ada lima cara berbeda (yang saya tahu) bahwa pengguna dapat menjadi anggota grup di OS X. Perintah ini tidak dijamin untuk menampilkan semua, atau bahkan apa pun, dari anggota mygroup , karena keanggotaan juga berasal dari pengguna ' kelompok utama ID , keanggotaan oleh pengguna UUID , warisan dari keanggotaan dari satu kelompok ke kelompok lain, dan keanggotaan yang dihitung oleh sistem, seperti kelompok orang .dscl . -read /Groups/mygroup GroupMembership

Jadi daripada mencoba melacak semua itu, sepertinya ide yang lebih baik untuk cukup memeriksa keanggotaan setiap pengguna pada sistem (menggunakan dsmemberutil ), dan itulah yang fungsi shell dan skrip di bawah ini lakukan.


Ini anggota naskah setara dengan fungsi shell, tetapi memiliki lebih bagus menangani input tidak valid:

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

Info tambahan:

Lima cara menjadi anggota kelompok adalah:

  1. PrimaryGroupID pengguna
  2. Terdaftar dalam Keanggotaan Grup grup
  3. UUID tercantum dalam GroupMembers grup
  4. Mewarisi keanggotaan grup X dengan menjadi anggota grup Y yang terdaftar di grup X NestedGroups
  5. Keanggotaan dihitung oleh sistem

Ini dapat dieksplorasi dengan perintah seperti dscl . -read /Groups/somegroup

Contoh 4 : Keanggotaan grup Operator Cetak __lpoperator_ diwarisi oleh anggota grup Administrator Cetak __lpadmin_, dan keanggotaan grup tersebut diwarisi oleh anggota grup admin .

Contoh 5 :

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

LIHAT JUGA
    id (1) , dscl (1) , dsmemberutil (1) , dseditgroup (8) , DirectoryServiceAttributes (7) , uuid (3)

Arne Stenström
sumber
7
Ini adalah jenis keanehan yang ada dalam pikiran saya ketika saya memberi tahu orang-orang bahwa sementara OS X sebagian besar indah di permukaannya, ada beberapa hal buruk yang tersembunyi di balik selimut.
Stefan Schmidt
+1 : Ini berfungsi dengan baik. Merci.
Slipp D. Thompson
Ini adalah info yang saya perlukan untuk mengetahui cara menghapus diri saya dari grup admin. Ternyata menghapus dengan nama pengguna tidak cukup, Anda juga perlu menghapus UUID, lihat github.com/drduh/macOS-Security-and-Privacy-Guide/issues/…
Jens Timmerman
10

Catatan: Ini adalah jawaban awal saya, ditulis sebelum saya menyadari jawaban ini masih memberikan hasil yang tidak lengkap . (Sebagai contoh, ia menemukan ada anggota semua orang kelompok!) Jadi saya menulis jawaban yang lebih baik, yang mencakup naskah yang daftar semua anggota sebuah kelompok di OS X .


Properti GroupMembership mygroup dapat dicetak dengan dscl seperti ini:

dscl . -read /Groups/mygroup GroupMembership

Tetapi ini tidak dijamin untuk menghasilkan semua (atau bahkan apa pun) anggota grup. Yang hilang adalah pengguna yang menjadi anggota grup hanya dengan menjadikannya sebagai ID grup utama mereka .

Contoh umum dari ini di OS X adalah akun login reguler, yang memiliki staf (grup 20) sebagai grup utama mereka, tetapi tidak terdaftar di properti GroupMembership grup staf .

Pengguna tersebut dapat ditemukan dengan mencari ID grup primer numerik (gid) seperti contoh ini untuk grup staf (gid 20):

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

dan numeric gid (PrimaryGroupID) dari mygroup ditemukan oleh:

dscl . -read /Groups/mygroup PrimaryGroupID
Arne Stenström
sumber
7

Untuk mendapatkan semua grup tempat pengguna berada , Anda dapat menggunakan yang berikut ini:

id -nG <username>

Contoh Output:

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

Dengan menggunakan perintah di atas, dimungkinkan untuk mendapatkan semua pengguna yang dimiliki grup :

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
Jay Brown
sumber
Ini adalah tip yang bagus untuk mendapatkan daftar grup yang menjadi milik pengguna. Tapi itu kebalikan dari apa yang diminta OP, yaitu daftar pengguna yang termasuk dalam grup.
wisbucky
@wisbucky inilah tepatnya yang saya cari. Saya sampai di sini mencari "daftar semua grup pengguna". Saya akan menyarankan suntingan untuk mengklarifikasi ini
Isaac
4

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

HATI-HATI: Perintah di atas tidak selalu menampilkan daftar lengkap SEMUA anggota grup. Misalnya untuk "staf" grup Anda hanya mendapatkan "root" sebagai anggota grup yang tidak lengkap. Untuk memeriksanya gunakan salah satu dari perintah berikut sebagai pengguna default (BUKAN "root"): id -GnATAUgroups

Akibatnya, Anda akan melihat semua grup yang menjadi anggota Anda. Salah satunya harus "staf". Jadi, selain "root" ada lebih banyak anggota "staf" grup, yang tidak terdaftar oleh perintah dscl . -read /Groups/[groupname] | grep GroupMembership. Hal yang sama berlaku untuk perintah dscacheutil -q group -a name staffyang juga menyarankan Anda bahwa hanya "root" yang merupakan anggota dari "staf" grup, yang jelas tidak lengkap.

Satu-satunya metode yang dapat diandalkan untuk benar-benar SEMUA anggota grup di terminal pada OSX sudah disediakan di sini oleh Arne Stenström. Ini menggunakan resp fungsi shell-nya. naskah cangkangnya. Keduanya bekerja dengan baik!

William Jackson
sumber
1

Perintah

Mirip dengan jawaban @ duperuser, yang berikut hanya akan mencetak pengguna grup admindengan spasi di antaranya:

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

Keluaran

Menjalankan perintah di atas akan menghasilkan sesuatu seperti ini:

root your_username someone_else

Kerusakan

The dscacheutilPerintah ini digunakan untuk permintaan informasi tentang berbagai kategori sistem layanan direktori tembolok. The -qpilihan memungkinkan Anda menentukan kategori yang Anda ingin query. Kategori yang tersedia adalah grup, host, mount, protokol, rpc, layanan, dan pengguna. Kami selanjutnya menanyakan kategori itu dengan menentukan pasangan nilai kunci dengan -aopsi. Dalam hal ini, kami ingin membuat daftar grup yang memiliki kunci namesama dengan nilai admin. The dscacheutilperintah di atas menghasilkan output seperti ini:

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

Selanjutnya kita pipa teks ini ke dalam grepdan memilih garis yang berisi string users:di awal. The -emerek pilihan grep mengenali ekspresi reguler . The ^menspesifikasikan karakter yang kita inginkan users:berada di awal baris.

Ini memberi kita

users: root yourusername

Akhirnya, kami meneruskan ini ke sed dan mengganti teks users:dengan string kosong. Dalam sed , huruf pertama ssarana untuk menggantikan. Teks antara pasangan garis miring pertama ( /users: /) adalah apa yang ingin kami ganti, dan pasangan garis miring berikutnya ( //) adalah apa yang ingin kami gantikan (dalam hal ini, tidak ada).

AmadeusDrZaius
sumber
0

Berikut ini adalah implementasi untuk masalah ini yang berasal dari implementasi dalam diskusi terkait . Rutin ini agak umum, dengan hook pencarian layanan direktori untuk platform / arsitektur tertentu, sehingga dapat digunakan tanpa modifikasi pada jaringan yang heterogen. Kami telah memasang tautan simbolis ke utilitas ini bernama zed. Asal lain untuk implementasi ini disebutkan di bagian atribusi dari skrip. Alat ini dimaksudkan untuk dijalankan pada setidaknya OSX, HP-UX, linux, dan SunOS, tetapi belumdiuji pada SunOS dan HP-UX. Script diuji sejauh mungkin di Ubuntu Linux 12.04 dan Mavericks OSX 10.9.1. Output dari skrip ini cocok dengan output untuk implementasi skrip shell pertama untuk masalah ini, dan karenanya dianggap benar.

#!/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 ([email protected] or [email protected])
#
# 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";
    }
}
Billy McCloskey
sumber