Successivo: , Precedente: , Su: Cloni   [Contenuti][Indice]


11.2.3 Stampare informazioni sull’utente

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: , Precedente: , Su: Cloni   [Contenuti][Indice]