Ich möchte oft den Anmeldenamen einer Benutzer-ID zuordnen. Da dies ein häufiger Anwendungsfall ist, habe ich mich dazu entschlossen, eine Shell-Funktion zu schreiben. Während ich hauptsächlich GNU / Linux-Distributionen verwende, versuche ich, meine Skripte so portabel wie möglich zu gestalten und zu überprüfen, ob meine Arbeit mit POSIX kompatibel ist.
Parse /etc/passwd
Der erste Ansatz, den ich versuchte, war das Parsen /etc/passwd(Verwenden awk).
awk -v uid="$uid" -F: '$3 == uid {print $1}' /etc/passwd
Das Problem bei diesem Ansatz ist jedoch, dass die Anmeldungen möglicherweise nicht lokal sind, z. B. kann die Benutzerauthentifizierung über NIS oder LDAP erfolgen.
Verwenden Sie den getentBefehl
Die Verwendung getent passwdist portabler als das Parsen, /etc/passwdda hierdurch auch nicht-lokale NIS- oder LDAP-Datenbanken abgefragt werden.
getent passwd "$uid" | cut -d: -f1
Leider getentscheint das Dienstprogramm nicht von POSIX angegeben zu werden.
Verwenden Sie den idBefehl
id ist das POSIX-standardisierte Dienstprogramm zum Abrufen von Daten zur Identität eines Benutzers.
BSD- und GNU-Implementierungen akzeptieren eine Benutzer-ID als Operanden:
Das heißt, es kann verwendet werden, um den Anmeldenamen zu drucken, der einer Benutzer-ID zugeordnet ist:
id -nu "$uid"
Die Angabe von Benutzer-IDs als Operand ist in POSIX jedoch nicht angegeben. Es wird nur die Verwendung eines Anmeldenamens als Operand beschrieben.
Kombinieren Sie alle oben genannten
Ich überlegte, ob ich die drei oben genannten Ansätze in etwa wie folgt kombinieren sollte:
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
}
Dies ist jedoch klobig, unelegant und - was noch wichtiger ist - nicht robust; Es wird mit einem Status ungleich Null beendet, wenn die Benutzer-ID ungültig oder nicht vorhanden ist. Bevor ich ein längeres und komplexeres Shell-Skript schreibe, das den Beendigungsstatus jedes Befehlsaufrufs analysiert und speichert, dachte ich, ich würde hier fragen:
Gibt es eine elegantere und portablere (POSIX-kompatible) Möglichkeit, den Anmeldenamen einer Benutzer-ID zuzuordnen?
getentnoch zurückgegeben idwird. Die einzige Möglichkeit, sie alle zu finden, besteht darin, alle Benutzer aufzulisten, sofern die Benutzerdatenbank dies zulässt. (In /etc/passwdWerken nach dort definierten Benutzern suchen , offensichtlich.)
/etc/passwdund /etc/shadowdieses Szenario getestet und überprüft, ob beide idund getent passwddas von Ihnen beschriebene Verhalten zutreffen . Wenn ich irgendwann ein System verwende, auf dem ein Benutzer mehrere Namen hat, mache ich dasselbe wie diese Systemdienstprogramme und behandle einfach das erste Vorkommen als den kanonischen Namen für diesen Benutzer.
setuid(some_id), und es gibt keine Anforderung, some_iddie Teil einer Benutzerdatenbank sein kann. Bei Benutzernamensräumen unter Linux kann dies zu einer lähmenden Annahme für Ihre Skripte werden.
getpwuid()Funktion lszu sein, mit der UIDs in Anmeldenamen übersetzt werden. Gilles 'Antwort ist eine direktere und effizientere Möglichkeit, dies zu erreichen.