รายชื่อสมาชิกทั้งหมดของกลุ่ม (Mac OS X)


56

ฉันลอง Googling แล้ว แต่ไม่ไปไหน ฉันจะแสดงรายการสมาชิกทั้งหมดของกลุ่มที่เรียกmygroupจากบรรทัดคำสั่งใน OS X ได้อย่างไร

$ dscl . list /groupsจะได้รับทุกกลุ่ม ... แต่ฉันจะดูสมาชิกแต่ละกลุ่มได้อย่างไร

คำตอบ:


40

คุณสามารถใช้ได้:

dscacheutil -q group -a name admin

หรือ:

dscacheutil -q group -a name staff

เป็นต้น


นี่เป็นวิธีที่ฉันชอบ peasy ง่ายและถูกต้อง ขอบคุณ!
TryTryAgain

นี่เป็นคำตอบที่ยอดเยี่ยมเนื่องจาก 90% ของกรณีการใช้งานสามารถแก้ไขได้ด้วยสิ่งนี้และไม่ใช่ด้วยสคริปต์ที่ซับซ้อนมากขึ้นซึ่งโพสต์เป็นคำตอบ
JakeGould

เพียงแค่เพิ่มสิ่งนี้เป็นนามแฝงในไฟล์เริ่มต้นเชลล์ของคุณและคุณสามารถทำให้มันเป็นคำสั่งหนึ่งคำบวกกับชื่อกลุ่ม
Neil Monroe

เมื่อฉันลอง "dscacheutil -q group" ฉันได้รับ 2 ย่อหน้าสำหรับกลุ่ม "admin" ทั้งสองมีชื่อเดียวกัน gid แต่มีรายชื่อผู้ใช้ต่างกัน ความคิดใด ๆ ขอบคุณ!
Golden Thumb

ไม่จำเป็นต้องสมบูรณ์ dscacheutil -q group -a name adminให้ผลลัพธ์เพียง 1 รายการเท่านั้นในขณะที่เชลล์สคริปต์ของผู้ตอบที่ตอบรับแล้วให้ผลลัพธ์ 2 รายการ
wisbucky

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


คำอธิบายบางอย่างสำหรับผู้ที่สนใจ:

มีห้าวิธีที่ต่างกัน (ที่ฉันรู้) ว่าผู้ใช้สามารถเป็นสมาชิกของกลุ่มใน OS X ได้คำสั่งไม่รับประกันว่าจะส่งออกทั้งหมดหรือแม้กระทั่งสมาชิกของกลุ่มmygroupเพราะสมาชิกยังมาจากผู้ใช้ ' กลุ่มหลักหมายเลขสมาชิกโดยผู้ใช้UUIDมรดกของการเป็นสมาชิกจากกลุ่มหนึ่งไปยังอีกและสมาชิกที่ได้รับการคำนวณโดยระบบเช่นกลุ่มทุกคน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

ข้อมูลเพิ่มเติม:

ห้าวิธีในการเป็นสมาชิกกลุ่มคือ:

  1. PrimaryGroupIDของผู้ใช้
  2. จดทะเบียนในGroupMembershipของกลุ่ม
  3. UUIDอยู่ในรายการGroupMembersของกลุ่ม
  4. การรับสมาชิกภาพของกลุ่ม X โดยเป็นสมาชิกของกลุ่ม Y ซึ่งอยู่ในกลุ่มNestedGroupsของ 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 ส่วนใหญ่สวยงามบนพื้นผิว แต่ก็มีสิ่งที่น่ารังเกียจซ่อนอยู่ใต้ฝาครอบ
Stefan Schmidt

+1 : สิ่งนี้ทำงานได้อย่างสมบูรณ์ Merci
Slipp D. Thompson

นี่คือข้อมูลที่ฉันต้องการเพื่อหาวิธีลบตัวเองออกจากกลุ่มผู้ดูแลระบบ ปรากฎว่าการลบโดยชื่อผู้ใช้นั้นไม่เพียงพอคุณต้องลบ UUID ดูgithub.com/drduh/macOS-Security-and-Privacy-Guide/issues/ …
Jens Timmerman

10

หมายเหตุ: นี่คือคำตอบของฉันเริ่มต้นเขียนก่อนที่ผมรู้คำตอบนี้ยังคงให้ผลที่ไม่สมบูรณ์ (ยกตัวอย่างเช่นมันพบว่าสมาชิกของไม่มีทุกคนกลุ่ม!) ดังนั้นฉันจึงเขียนคำตอบที่ดีซึ่งรวมถึงสคริปต์ที่แสดงสมาชิกทั้งหมดของกลุ่มใน OS X


mygroup GroupMembership คุณสมบัติ 's สามารถพิมพ์ด้วยdsclเช่นนี้

dscl . -read /Groups/mygroup GroupMembership

แต่สิ่งนี้ไม่รับประกันว่าจะให้สมาชิกของกลุ่มทั้งหมด (หรือแม้แต่) สิ่งที่ขาดหายไปคือผู้ใช้ที่เป็นสมาชิกของกลุ่มโดยให้เป็นID กลุ่มหลักเท่านั้น

ตัวอย่างทั่วไปของสิ่งนี้ใน OS X เป็นบัญชีเข้าสู่ระบบปกติซึ่งมีพนักงาน (กลุ่ม 20) เป็นกลุ่มหลักของพวกเขา แต่ไม่ได้ระบุไว้ในคุณสมบัติ GroupMembership ของกลุ่มพนักงาน

ผู้ใช้เหล่านั้นสามารถพบได้โดยค้นหาID กลุ่มหลักที่เป็นตัวเลข(gid) เช่นตัวอย่างนี้สำหรับกลุ่มพนักงาน (gid 20):

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

และตัวเลข gid (PrimaryGroupID) ของmygroupพบได้โดย:

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

ยูนิกซ์ :

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

@wuckyucky นี่คือสิ่งที่ฉันเป็นหลังจากนั้น ฉันมาที่นี่เพื่อค้นหา "รายชื่อกลุ่มผู้ใช้ทั้งหมด" ฉันจะแนะนำให้แก้ไขเพื่ออธิบายสิ่งนี้
Isaac

4

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

ระวังตัว: คำสั่งด้านบนไม่ได้แสดงรายการทั้งหมดของสมาชิกกลุ่มทั้งหมด เช่นสำหรับกลุ่ม "พนักงาน" คุณจะได้รับ "รูท" ในฐานะสมาชิกกลุ่มซึ่งไม่สมบูรณ์ ในการตรวจสอบให้ใช้คำสั่งอย่างใดอย่างหนึ่งต่อไปนี้ในฐานะผู้ใช้เริ่มต้น (ไม่ใช่ "รูท"): id -Gnหรือgroups

เป็นผลให้คุณจะเห็นทุกกลุ่มผู้ใช้เข้าสู่ระบบเริ่มต้นของคุณเป็นสมาชิก หนึ่งในนั้นควรเป็น "พนักงาน" ดังนั้นนอกเหนือจาก "ราก" มีสมาชิกมากขึ้นของกลุ่ม "พนักงาน" dscl . -read /Groups/[groupname] | grep GroupMembershipซึ่งไม่ได้ระบุไว้โดยคำสั่ง สิ่งเดียวกันนี้สำหรับคำสั่งdscacheutil -q group -a name staffที่แนะนำให้คุณทราบว่า "root" เท่านั้นที่เป็นสมาชิกของกลุ่ม "เจ้าหน้าที่" ซึ่งไม่สมบูรณ์อย่างเห็นได้ชัด

วิธีการที่เชื่อถือได้เพียงวิธีเดียวที่จะทำให้สมาชิกทั้งหมดของกลุ่มในเทอร์มินัลบน OSX ได้รับการจัดหาให้โดย Arne Stenströ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ตัวเลือก ในกรณีนี้เราต้องการที่จะแสดงรายชื่อกลุ่มที่มีความสำคัญเท่ากับค่าname คำสั่งadminดังกล่าวdscacheutilสร้างผลลัพธ์เช่นนี้:

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

เราถัดไปท่อข้อความลงในนี้grepและเลือกออกบรรทัดที่มีสตริงusers:ที่จุดเริ่มต้น -eตัวเลือกทำให้ grep รู้จักการแสดงออกปกติ ^ตัวอักษรระบุว่าเราต้องการusers:ที่จะเป็นจุดเริ่มต้นของบรรทัด

สิ่งนี้ทำให้เรา

users: root yourusername

ในที่สุดเราก็ผ่านสิ่งนี้ไปยัง sed และแทนที่ข้อความusers:ด้วยสตริงว่าง ในsed , ตัวอักษรตัวแรกsหมายถึงการทดแทน ข้อความระหว่างเครื่องหมายทับคู่แรก ( /users: /) คือสิ่งที่เราต้องการแทนที่และเครื่องหมายทับคู่ถัดไป ( //) คือสิ่งที่เราต้องการแทนที่ (ในกรณีนี้ไม่มีอะไร)


0

นี่คือการดำเนินการสำหรับปัญหานี้ซึ่งได้มาจากการดำเนินงานในการอภิปรายที่เกี่ยวข้อง รูทีนนั้นค่อนข้างทั่วไปโดยมี hook การค้นหาบริการไดเรกทอรีสำหรับแพลตฟอร์ม / สถาปัตยกรรมเฉพาะใด ๆ ดังนั้นจึงสามารถใช้งานได้โดยไม่ต้องดัดแปลงบนเครือข่ายที่ต่างกัน เราได้ติดตั้งลิงก์สัญลักษณ์ไปยังยูทิลิตี้นี้zedแล้ว ต้นกำเนิดอื่น ๆ สำหรับการใช้งานนี้ถูกกล่าวถึงในส่วนที่มาของสคริปต์ เครื่องมือนี้มีจุดประสงค์เพื่อให้ทำงานบน OSX, HP-UX, linux และ SunOS เป็นอย่างน้อย แต่ยังไม่ได้รับทดสอบบน SunOS และ 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.