Spesso desidero ottenere il nome di accesso associato a un ID utente e poiché è dimostrato che è un caso d'uso comune, ho deciso di scrivere una funzione di shell per farlo. Mentre utilizzo principalmente le distribuzioni GNU / Linux, provo a scrivere i miei script per essere il più portatile possibile e per verificare che ciò che sto facendo sia compatibile con POSIX.
Parse /etc/passwd
Il primo approccio che ho provato è stato di analizzare /etc/passwd
(usando awk
).
awk -v uid="$uid" -F: '$3 == uid {print $1}' /etc/passwd
Tuttavia, il problema con questo approccio è che gli accessi potrebbero non essere locali, ad esempio l'autenticazione dell'utente potrebbe avvenire tramite NIS o LDAP.
Usa il getent
comando
L'utilizzo getent passwd
è più portatile dell'analisi in /etc/passwd
quanto esegue anche query su database NIS o LDAP non locali.
getent passwd "$uid" | cut -d: -f1
Sfortunatamente, l' getent
utilità non sembra essere specificata da POSIX.
Usa il id
comando
id
è l'utility standardizzata POSIX per ottenere dati sull'identità di un utente.
Le implementazioni di BSD e GNU accettano un ID utente come operando:
Ciò significa che può essere utilizzato per stampare il nome di accesso associato a un ID utente:
id -nu "$uid"
Tuttavia, fornire ID utente come operando non è specificato in POSIX; descrive solo l'uso di un nome di accesso come operando.
Combinando tutto quanto sopra
Ho considerato di combinare i tre approcci sopra in qualcosa di simile al seguente:
get_username(){
uid="$1"
# First try using getent
getent passwd "$uid" | cut -d: -f1 ||
# Next try using the UID as an operand to id.
id -nu "$uid" ||
# As a last resort, parse `/etc/passwd`.
awk -v uid="$uid" -F: '$3 == uid {print $1}' /etc/passwd
}
Tuttavia, questo è goffo, inelegante e - soprattutto - non robusto; esce con uno stato diverso da zero se l'ID utente non è valido o non esiste. Prima di scrivere uno script di shell più lungo e clunkier che analizza e memorizza lo stato di uscita di ogni invocazione di comando, ho pensato di chiedere qui:
Esiste un modo più elegante e portatile (compatibile POSIX) per ottenere il nome di accesso associato a un ID utente?
getent
né id
restituiranno nulla oltre la prima corrispondenza; l'unico modo per trovarli tutti è enumerare tutti gli utenti, se il database degli utenti lo consente. (Cercare /etc/passwd
opere per gli utenti definiti lì, ovviamente.)
/etc/passwd
e /etc/shadow
per testare questo scenario e verificato che entrambi id
e getent passwd
comportarsi come descritto. Se, a un certo punto, finissi per usare un sistema in cui un utente ha più nomi, farò lo stesso di questi programmi di utilità del sistema e tratterò semplicemente la prima occorrenza come il nome canonico per quell'utente.
setuid(some_id)
e non è necessario che some_id
faccia parte di alcun database utente. Con cose come gli spazi dei nomi degli utenti su Linux, questo può diventare un presupposto paralizzante per i tuoi script.
getpwuid()
funzione che ls
utilizza per tradurre gli UID in nomi di login. La risposta di Gilles è un modo più diretto ed efficiente per raggiungere questo obiettivo.