Listar todos los miembros de un grupo (Mac OS X)

56

Intenté buscar en Google pero no llegué a ninguna parte. ¿Cómo puedo enumerar a todos los miembros de un grupo llamado mygroupdesde la línea de comandos en OS X?

$ dscl . list /groupsme conseguirá todos los grupos ... pero ¿cómo puedo ver los miembros de cada grupo?

Meltemi
fuente

Respuestas:

41

Puedes usar:

dscacheutil -q group -a name admin

o:

dscacheutil -q group -a name staff

etc.

duperuser
fuente
Este es mi método favorito. Fácil, fácil y preciso. ¡Gracias!
Try TryAgain
Esta es una gran respuesta ya que el 90% de los casos de uso se pueden resolver con esto y no con los scripts más elaborados que se han publicado como respuestas.
JakeGould
Simplemente agregue esto como un alias en su archivo de inicio de shell y puede convertirlo en un comando de una palabra más el nombre del grupo.
Neil Monroe
Cuando intenté "dscacheutil -q group" obtuve 2 párrafos para el grupo "admin". Los dos tienen el mismo nombre, gid, pero una lista de usuarios diferente. ¿Alguna idea? ¡Gracias!
Golden Thumb
No necesariamente completo. dscacheutil -q group -a name adminsolo me dio 1 resultado, mientras que el script de shell de la respuesta aceptada me dio 2 resultados.
wisbucky
64

No hay un comando estándar que enumere todos los miembros de un grupo en OS X, así que aquí hay una función de shell que hace eso:

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

Copie la línea de comandos anterior en la Terminal y luego escriba (donde mygroup es el nombre de un grupo existente).members mygroup


Alguna explicación para los interesados:

Hay cinco maneras diferentes (que yo sepa) de que un usuario puede ser miembro de un grupo en OS X. No se garantiza que el comando genere todos, o incluso ninguno, de los miembros de mygroup , porque la membresía también proviene de los usuarios ' ID de grupo principal , membresía por UUID del usuario , herencia de membresía de un grupo a otro y membresías calculadas por el sistema, como el grupo todos .dscl . -read /Groups/mygroup GroupMembership

Entonces, en lugar de tratar de hacer un seguimiento de todo eso, parece una mejor idea simplemente verificar la membresía de cada usuario en el sistema (usando dsmemberutil ), y eso es lo que hacen la función de shell y el script a continuación.


Este script de miembros es equivalente a la función de shell, pero tiene un mejor manejo de la entrada no válida:

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

Información suplementaria:

Las cinco formas de ser miembro del grupo son:

  1. El ID de grupo primario del usuario
  2. Listado en la Membresía de grupo del grupo
  3. UUID enumerado en los GroupMembers del grupo
  4. Membresía heredada del grupo X al ser miembro del grupo Y que se encuentra en los Grupos Anidados del grupo X
  5. Membresía calculada por el sistema

Estos se pueden explorar con comandos como dscl . -read /Groups/somegroup

Ejemplo de 4 : Composición de la impresión __lpoperator_ grupo de operadores se hereda por miembros del grupo de impresión __lpadmin_ administrador, y la pertenencia a ese grupo es heredado por los miembros del administrador de grupo.

Ejemplo de 5 :

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

VEA TAMBIÉN
    id (1) , dscl (1) , dsmemberutil (1) , dseditgroup (8) , DirectoryServiceAttributes (7) , uuid (3)

Arne Stenström
fuente
77
Este es el tipo de peculiaridades que tengo en mente cuando le digo a la gente que si bien OS X es principalmente hermoso en la superficie, tiene algunas cosas desagradables ocultas debajo de las cubiertas.
Stefan Schmidt
+1 : esto funciona sólidamente. Merci
Slipp D. Thompson
Esta es la información que necesitaba para descubrir cómo eliminarme del grupo de administración. Resulta que eliminar por nombre de usuario no es suficiente, también debe eliminar el UUID, consulte github.com/drduh/macOS-Security-and-Privacy-Guide/issues/…
Jens Timmerman el
10

Nota: Esta fue mi respuesta inicial, escrita antes de darme cuenta de que esta respuesta todavía da un resultado incompleto . (Por ejemplo, se encuentra ningún miembro de la todos grupo!) Así que escribí una mejor respuesta, que consta de una secuencia de comandos que enumera todos los miembros de un grupo en OS X .


mygroup 's propiedad GroupMembership se puede imprimir con dscl como esto:

dscl . -read /Groups/mygroup GroupMembership

Pero no se garantiza que esto genere todos (o incluso ninguno) de los miembros del grupo. Lo que falta son los usuarios que son miembros del grupo solo al tenerlo como su ID de grupo principal .

Un ejemplo común de esto en OS X son las cuentas de inicio de sesión regulares, que tienen al personal (grupo 20) como su grupo principal, pero no figuran en la propiedad GroupMembership del grupo de personal .

Esos usuarios se pueden encontrar buscando el ID numérico del grupo primario (gid) como este ejemplo para el grupo de personal (gid 20):

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

y el gid numérico (PrimaryGroupID) de mygroup se encuentra por:

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

Para obtener todos los grupos en los que se encuentra un usuario , puede usar lo siguiente:

id -nG <username>

Salida de ejemplo:

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

Utilizando el comando anterior, es posible obtener todos los usuarios que pertenecen a un grupo :

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
fuente
Este es un buen consejo para obtener una lista de grupos a los que pertenece un usuario. Pero es lo opuesto a lo que pedía el OP, que es una lista de usuarios que pertenecen a un grupo.
wisbucky
@wisbucky esto es precisamente lo que estaba buscando. Llegué aquí buscando "enumerar todos los grupos de un usuario". Sugeriré una edición para aclarar esto
Isaac
4

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

TENGA CUIDADO: El comando anterior no siempre muestra una lista completa de TODOS los miembros del grupo. Por ejemplo, para el grupo "personal" solo se obtiene "raíz" como miembro del grupo que está incompleto. Para verificarlo, use uno de los siguientes comandos como usuario predeterminado (NO "root"): id -GnOgroups

Como resultado, verá todos los grupos a los que pertenece su usuario predeterminado. Uno de ellos debería ser "personal". Por lo tanto, además de "root" hay más miembros del grupo "staff", que no están listados por el comando dscl . -read /Groups/[groupname] | grep GroupMembership. Lo mismo ocurre con el comando dscacheutil -q group -a name staffque también sugiere que solo "root" es un miembro del grupo "staff", que obviamente está incompleto.

Arne Stenström ya proporciona aquí el único método confiable para obtener TODOS los miembros de un grupo en el terminal en OSX. Esto está usando su función de shell resp. Su guión de shell. ¡Ambos funcionan muy bien!

William Jackson
fuente
1

Mando

Similar a la respuesta de @ duperuser, lo siguiente imprimirá solo a los usuarios del grupo admincon espacios intermedios:

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

Salida

Ejecutar el comando anterior producirá algo como esto:

root your_username someone_else

Descompostura

El dscacheutilcomando se utiliza para consultar información sobre varias categorías de la memoria caché del servicio de directorio del sistema. La -qopción le permite especificar la categoría que desea consultar. Las categorías disponibles son grupo, host, montaje, protocolo, rpc, servicio y usuario. Además, consultamos esa categoría especificando un par de valores clave con la -aopción. En este caso, queremos enumerar el grupo que tiene la clave nameigual al valor admin. El dscacheutilcomando anterior produce resultados como este:

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

A continuación, canalizamos este texto grepy seleccionamos la línea que contiene la cadena users:al principio. La -eopción hace que grep reconozca expresiones regulares . El ^carácter especifica que queremos users:estar al comienzo de la línea.

Esto nos da

users: root yourusername

Finalmente, pasamos esto a sed y reemplazamos el texto users:con la cadena vacía. En sed , la primera letra ssignifica sustituir. El texto entre el primer par de barras ( /users: /) es lo que queremos reemplazar, y el siguiente par de barras ( //) es lo que queremos sustituir (en este caso, nada).

AmadeusDrZaius
fuente
0

Aquí hay una implementación para este problema que se derivó de una implementación en una discusión relacionada . La rutina es algo genérica, con un enlace de búsqueda de servicio de directorio para cualquier plataforma / arquitectura específica, por lo que puede usarse sin modificación en una red heterogénea. Hemos instalado un enlace simbólico a esta utilidad llamada zed. Otros orígenes para esta implementación se mencionan en la sección de atribución del script. Esta herramienta está diseñada para ejecutarse al menos en OSX, HP-UX, Linux y SunOS, pero no ha sidoprobado en SunOS y HP-UX. La secuencia de comandos se probó en la medida de lo posible en Ubuntu Linux 12.04 y Mavericks OSX 10.9.1. El resultado de este script coincide con el resultado de la primera implementación del script de shell para este problema, y ​​por lo tanto se considera correcto.

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