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