grp — Base de datos de grupos Unix

Propósito:Leer datos de grupo de la base de datos de grupo Unix.

El módulo grp se puede usar para leer información sobre grupos Unix de la base de datos del grupo (generalmente /etc/group). La interfaz de solo lectura devuelve objetos tipo tupla con atributos con nombre para los campos estándar de un registro de grupo.

Índice Atributo Significado
0 gr_name Nombre
1 gr_passwd Contraseña, si existe (encriptada)
2 gr_gid Identificador numérico (número entero)
3 gr_mem Nombres de miembros del grupo

Los valores de nombre y contraseña son cadenas, el GID es un número entero y los miembros se informan como una lista de cadenas.

Consultar todos los grupos

Este ejemplo imprime un informe de todos los grupos «reales» en un sistema, incluidos sus miembros (donde «real» se define como que tiene un nombre que no comienza con «_»). Para cargar la base de datos de contraseñas completa, usa getgrall().

grp_getgrall.py
import grp
import textwrap

# Load all of the user data, sorted by username
all_groups = grp.getgrall()
interesting_groups = {
    g.gr_name: g
    for g in all_groups
    if not g.gr_name.startswith('_')
}
print(len(interesting_groups.keys()))

# Find the longest length for a few fields
name_length = max(len(k) for k in interesting_groups) + 1
gid_length = max(len(str(u.gr_gid))
                 for u in interesting_groups.values()) + 1

# Set the members field width to avoid table columns
# wrapping
members_width = 19

# Print report headers
fmt = ' '.join(['{:<{name_length}}',
                '{:{gid_length}}',
                '{:<{members_width}}',
                ])
print(fmt.format('Name',
                 'GID',
                 'Members',
                 name_length=name_length,
                 gid_length=gid_length,
                 members_width=members_width))
print('-' * name_length,
      '-' * gid_length,
      '-' * members_width)

# Print the data
prefix = ' ' * (name_length + gid_length + 2)
for name, g in sorted(interesting_groups.items()):
    # Format members to start in the column on the same line but
    # wrap as needed with an indent sufficient to put the
    # subsequent lines in the members column. The two indent
    # prefixes need to be the same to compute the wrap properly,
    # but the first should not be printed so strip it.
    members = textwrap.fill(
        ', '.join(g.gr_mem),
        initial_indent=prefix,
        subsequent_indent=prefix,
        width=members_width + len(prefix),
    ).strip()
    print(fmt.format(g.gr_name,
                     g.gr_gid,
                     members,
                     name_length=name_length,
                     gid_length=gid_length,
                     members_width=members_width))

El valor de retorno es una lista con un orden indefinido, por lo que debe ordenarse antes de imprimir el informe.

$ python3 grp_getgrall.py

34
Name                            GID         Members
------------------------------- ----------- -------------------
accessibility                            90
admin                                    80 root
authedusers                              50
bin                                       7
certusers                                29 root, _jabber,
                                            _postfix, _cyrus,
                                            _calendar, _dovecot
com.apple.access_disabled               396
com.apple.access_ftp                    395
com.apple.access_screensharing          398
com.apple.access_sessionkey             397
com.apple.access_ssh                    399
com.apple.sharepoint.group.1            701 dhellmann
consoleusers                             53
daemon                                    1 root
dialer                                   68
everyone                                 12
group                                    16
interactusers                            51
kmem                                      2 root
localaccounts                            61
mail                                      6 _teamsserver
netaccounts                              62
netusers                                 52
network                                  69
nobody                           4294967294
nogroup                                  -1
operator                                  5 root
owner                                    10
procmod                                   9 root
procview                                  8 root
staff                                    20 root
sys                                       3 root
tty                                       4 root
utmp                                     45
wheel                                     0 root

Membresías grupales para un usuario

Otra tarea común podría ser imprimir una lista de todos los grupos para un usuario dado:

grp_groups_for_user.py
import grp

username = 'dhellmann'
group_names = set(
    g.gr_name
    for g in grp.getgrall()
    if username in g.gr_mem
)
print(username, 'belongs to:', ', '.join(sorted(group_names)))

El conjunto de nombres de grupo únicos se ordena antes de que se impriman.

$ python3 grp_groups_for_user.py

dhellmann belongs to: _appserveradm, _appserverusr, _lpadmin, ad
min, com.apple.sharepoint.group.1

Encontrar un grupo por nombre

Al igual que con pwd, también es posible consultar información sobre un grupo específico, ya sea por nombre o identificación numérica.

grp_getgrnam.py
import grp

name = 'admin'
info = grp.getgrnam(name)
print('Name    :', info.gr_name)
print('GID     :', info.gr_gid)
print('Password:', info.gr_passwd)
print('Members :', ', '.join(info.gr_mem))

El grupo admin tiene dos miembros:

$ python3 grp_getgrnam.py

Name    : admin
GID     : 80
Password: *
Members : root, dhellmann

Encontrar un grupo por ID

Para identificar el grupo que ejecuta el proceso actual, combina getgrgid() con os.getgid().

grp_getgrgid_process.py
import grp
import os

gid = os.getgid()
group_info = grp.getgrgid(gid)
print('Currently running with GID={} name={}'.format(
    gid, group_info.gr_name))
$ python3 grp_getgrgid_process.py

Currently running with GID=20 name=staff

Y para obtener el nombre del grupo basado en los permisos de un archivo, busca el grupo devuelto por os.stat().

grp_getgrgid_fileowner.py
import grp
import os

filename = 'grp_getgrgid_fileowner.py'
stat_info = os.stat(filename)
owner = grp.getgrgid(stat_info.st_gid).gr_name

print('{} is owned by {} ({})'.format(
    filename, owner, stat_info.st_gid))

El registro de estado del archivo incluye datos de propiedad y permiso para el archivo o directorio.

$ python3 grp_getgrgid_fileowner.py

grp_getgrgid_fileowner.py is owned by staff (20)

Ver también