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 getentcomando
L'utilizzo getent passwdè più portatile dell'analisi in /etc/passwdquanto esegue anche query su database NIS o LDAP non locali.
getent passwd "$uid" | cut -d: -f1
Sfortunatamente, l' getentutilità non sembra essere specificata da POSIX.
Usa il idcomando
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?
getentné idrestituiranno nulla oltre la prima corrispondenza; l'unico modo per trovarli tutti è enumerare tutti gli utenti, se il database degli utenti lo consente. (Cercare /etc/passwdopere per gli utenti definiti lì, ovviamente.)
/etc/passwde /etc/shadowper testare questo scenario e verificato che entrambi ide getent passwdcomportarsi 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_idfaccia 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 lsutilizza per tradurre gli UID in nomi di login. La risposta di Gilles è un modo più diretto ed efficiente per raggiungere questo obiettivo.