grp - Database dei Gruppi di Unix

Scopo: Legge dati sui gruppi dal database dei gruppi di Unix

Il modulo grp può essere usato per leggere informazioni sui gruppi Unix dal database dei gruppi (in genere /etc/group). L'interfaccia a sola lettura ritorna oggetti tipo tupla con attributi nominali per i campi standard di un record che rappresenta un gruppo.

INDICE ATTRIBUTO SIGNIFICATO
0 gr_name Nome
1 gr_passwd La password, se esiste (criptata)
2 pw_gid Id Gruppo (intero)
3 pw_mem I nomi dei membri del gruppo

I nomi e le password sono entrambi valori stringa, GID è un intero, ed i membri sono riportati come lista di stringhe.

Interrogare Tutti i Gruppi

Questo esempio stampa un elenco di tutti i gruppi "reali" su di un sistema, compresi i loro membri (laddove "reale" è inteso come chi ha un nome che non inizia per "_"). Per caricare l'intero database, si usa getgrall().

# grp_getgrall.py

import grp
import textwrap

# Carica tutti i dati dei gruppi, ordinati per nome
all_groups = grp.getgrall()
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()))

# Trova la lunghezza massima di alcuni campi
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

# Imposta la larghezza del campo dei membri per evitare il ritorno a campo
# nelle colonne della tabella
members_width = 19

# Stampa le intestazioni del report
fmt = ' '.join(['{:<{name_length}}',
                '{:{gid_length}}',
                '{:<{members_width}}',
                ])
print(fmt.format('Nome',
                 'GID',
                 'Membri',
                 name_length=name_length,
                 gid_length=gid_length,
                 members_width=members_width))
print('-' * name_length,
      '-' * gid_length,
      '-' * members_width)

# Stampa i dati
prefix = ' ' * (name_length + gid_length + 2)
for name, g in sorted(interesting_groups.items()):
    # Formatta i membri in modo che partano nella colonna sulla stessa riga ma
    # li racchiude come necessario con una indentazione sufficiente per
    # inserire le righe seguenti alla stessa altezza nella colonna membri
    # I due prefissi di indentazione devono essere uguali per calcolare
    # propriamente l'indentazione ma il primo non dovrebbe essere stampato,
    # quindi viene eliminato.
    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))

Il valore restituito è una lista non ordinata, quindi occorre ordinarla prima di stampare il risultato.

$ python3 grp_getgrall.py

82
Nome                 GID    Membri             
-------------------- ------ -------------------
adm                       4 syslog, robby      
audio                    29 pulse              
avahi                   126                    
avahi-autoipd           123                    
backup                   34                    
bin                       2                    
bluetooth               115                    
cdrom                    24 robby              
colord                  130                    
crontab                 105                    
daemon                    1                    
dialout                  20                    
dictd                   137                    
dip                      30 robby              
disk                      6                    
docker                  998 robby              
fax                      21                    
floppy                   25                    
games                    60                    
gdm                     138                    
geoclue                 122                    
git                     999 robby              
gnats                    41                    
input                   107                    
irc                      39                    
kmem                     15                    
kvm                     108                    
lightdm                 128                    
list                     38                    
lp                        7                    
lpadmin                 114 robby              
mail                      8                    
man                      12                    
messagebus              106                    
mlocate                 119                    
mongodb                 135                    
netdev                  117                    
news                      9                    
nm-openvpn              133                    
nogroup               65534                    
nopasswdlogin           129                    
nvidia-persistenced     136                    
operator                 37                    
plugdev                  46 robby              
postdrop                141                    
postfix                 140                    
postgres                139                    
proxy                    13                    
pulse                   131                    
pulse-access            132                    
render                  109                    
robby                  1000 git                
root                      0                    
rtkit                   112                    
sambashare              134 robby              
saned                   127                    
sasl                     45                    
scanner                 124 saned              
shadow                   42                    
src                      40                    
ssh                     121                    
ssl-cert                116 postgres           
staff                    50                    
sudo                     27 robby              
sys                       3                    
syslog                  110                    
systemd-coredump        113                    
systemd-journal         101                    
systemd-network         102                    
systemd-resolve         103                    
systemd-timesync        104                    
tape                     26                    
tcpdump                 120                    
tss                     111                    
tty                       5 syslog             
users                   100                    
utmp                     43                    
uucp                     10                    
uuidd                   118                    
video                    44                    
voice                    22                    
www-data                 33                    

Appartenenza ad un Gruppo per un Utente

Un altro comune compito potrebbe essere quello di stampare una lista di tutti i gruppi dato un utente.

# grp_groups_for_user.py

import grp

username = 'robby'
group_names = set(
    g.gr_name
    for g in grp.getgrall()
    if username in g.gr_mem
)
print(username, 'appartiene a:', ', '.join(sorted(group_names)))

Un insieme di nomi di gruppo univoci viene ordinato prima di essere stampato.

$ python3 grp_groups_for_user.py

robby appartiene a: adm, cdrom, dip, docker, git, lpadmin, plugdev, sambashare, sudo

Trovare un Gruppo per Nome

Così come per pwd è anche possibile cercare informazioni circa uno specifico gruppo, sia per nome che per identificativo numerico.

# grp_getgrnam.py

import grp

name = 'adm'
info = grp.getgrnam(name)
print('Nome    :', info.gr_name)
print('GID     :', info.gr_gid)
print('Password:', info.gr_passwd)
print('Membri  :', ', '.join(info.gr_mem))

Il gruppo adm ha due membri.

$ python3 grp_getgrnam.py

Nome    : adm
GID     : 4
Password: x
Membri  : syslog, robby

Trovare un Gruppo per Identificativo

Per identificare un gruppo che ha in esecuzione il processo corrente, si combina getgrgid() con os.getgid().

# grp_getgrgid_process.py

import grp
import os

gid = os.getgid()
group_info = grp.getgrgid(gid)
print('Attualmente in esecuzione con GID={} nome={}'.format(
    gid, group_info.gr_name))
$ python3 grp_getgrgid_process.py

Attualmente in esecuzione con GID=1000 nome=robby

Per ottenere il nome del gruppo in base ai permessi su di un file, ci cerca il gruppo ritornato da 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('Il proprietario di {} è {} ({})'.format(
    filename, owner, stat_info.st_gid))

Il record dello stato del file comprende i dati di permesso e proprietà per un file o directory.

$ python3 grp_getgrgid_fileowner.py

Il proprietario di grp_getgrgid_fileowner.py è robby (1000)

Vedere anche:

grp
La documentazione della libreria standard per questo modulo.
pwd
Il modulo pwd legge informazioni sugli utenti dal database delle password
spwd
Accesso al database delle password sicuro per sistemi che utilizzano il password shadowing.
os
Interfacce di sistema operativo