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 getent
Befehl
Die Verwendung getent passwd
ist portabler als das Parsen, /etc/passwd
da hierdurch auch nicht-lokale NIS- oder LDAP-Datenbanken abgefragt werden.
getent passwd "$uid" | cut -d: -f1
Leider getent
scheint das Dienstprogramm nicht von POSIX angegeben zu werden.
Verwenden Sie den id
Befehl
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?
getent
noch zurückgegeben id
wird. Die einzige Möglichkeit, sie alle zu finden, besteht darin, alle Benutzer aufzulisten, sofern die Benutzerdatenbank dies zulässt. (In /etc/passwd
Werken nach dort definierten Benutzern suchen , offensichtlich.)
/etc/passwd
und /etc/shadow
dieses Szenario getestet und überprüft, ob beide id
und getent passwd
das 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_id
die Teil einer Benutzerdatenbank sein kann. Bei Benutzernamensräumen unter Linux kann dies zu einer lähmenden Annahme für Ihre Skripte werden.
getpwuid()
Funktion ls
zu sein, mit der UIDs in Anmeldenamen übersetzt werden. Gilles 'Antwort ist eine direktere und effizientere Möglichkeit, dies zu erreichen.