Successivo: Programma split, Precedente: Programma egrep, Su: Cloni [Contenuti][Indice]
Il programma di utilità id
elenca i numeri identificativi (ID)
reali ed effettivi di un utente, e l’insieme dei gruppi a cui l’utente
appartiene, se ve ne sono.
id
stampa i numeri identificativi di utente e di gruppo solo se
questi sono differenti da quelli reali. Se possibile, id
elenca
anche i corrispondenti nomi di utente e di gruppo.
L’output potrebbe essere simile a questo:
$ id -| uid=1000(arnold) gid=1000(arnold) groups=1000(arnold),4(adm),7(lp),27(sudo)
Questa informazione è parte di ciò che è reso disponibile dal vettore
PROCINFO
di gawk
(vedi la sezione Variabili predefinite).
Comunque, il programma di utilità id
fornisce un output più
comprensibile che non una semplice lista di numeri.
Ecco una versione semplice di id
scritta in awk
.
Usa le funzioni di libreria che riguardano il database degli utenti
(vedi la sezione Leggere la lista degli utenti)
e le funzioni di libreria che riguardano il database dei gruppi
(vedi la sezione Leggere la lista dei gruppi)
contenute
in
Una libreria di funzioni awk
.
Il programma è abbastanza semplice. Tutto il lavoro è svolto nella regola
BEGIN
. I numeri ID di utente e di gruppo sono ottenuti da
PROCINFO
.
Il codice è ripetitivo. La riga nel database degli utenti che descrive
l’ID reale dell’utente è divisa in parti, separate tra loro da ‘:’.
Il nome è il primo campo. Un codice analogo è usato per l’ID effettivo, e
per i numeri che descrivono i gruppi:
# id.awk --- implement id in awk # # Richiede funzioni di libreria per utente e gruppo # l'output è: # uid=12(pippo) euid=34(pluto) gid=3(paperino) \ # egid=5(paperina) groups=9(nove),2(due),1(uno)
BEGIN { uid = PROCINFO["uid"] euid = PROCINFO["euid"] gid = PROCINFO["gid"] egid = PROCINFO["egid"]
printf("uid=%d", uid) pw = getpwuid(uid) stampa_primo_campo(pw)
if (euid != uid) { printf(" euid=%d", euid) pw = getpwuid(euid)
stampa_primo_campo(pw) }
printf(" gid=%d", gid) pw = getgrgid(gid) stampa_primo_campo(pw) if (egid != gid) { printf(" egid=%d", egid) pw = getgrgid(egid) stampa_primo_campo(pw) } for (i = 1; ("group" i) in PROCINFO; i++) { if (i == 1) printf(" gruppi=") group = PROCINFO["group" i] printf("%d", group) pw = getgrgid(group) stampa_primo_campo(pw) if (("group" (i+1)) in PROCINFO) printf(",") } print "" } function stampa_primo_campo(str, a) { if (str != "") { split(str, a, ":") printf("(%s)", a[1]) } }
Il test incluso nel ciclo for
è degno di nota.
Ogni ulteriore gruppo nel vettore PROCINFO
ha come indice da
"group1"
a "groupN"
dove il numero
N è il numero totale di gruppi ulteriori).
Tuttavia, non si sa quanti di questi gruppi ci siano per un dato utente.
Questo ciclo inizia da uno, concatena il valore di ogni iterazione con
"group"
, e poi usando l’istruzione in
verifica se quella
chiave è nel vettore (vedi la sezione Come esaminare un elemento di un vettore). Quando i
è
incrementato oltre l’ultimo gruppo presente nel vettore, il ciclo termina.
Il ciclo funziona correttamente anche se non ci sono ulteriori gruppi; in quel caso la condizione risulta falsa fin dal primo controllo, e il corpo del ciclo non viene mai eseguito.
La funzione stampa_primo_campo()
semplicemente incapsula quelle parti di
codice che vengono usate ripetutamente, rendendo il programma più conciso e
ordinato.
In particolare, inserendo in questa funzione il test per la stringa nulla
consente di risparmiare parecchie righe di programma.
Successivo: Programma split, Precedente: Programma egrep, Su: Cloni [Contenuti][Indice]