Ich möchte alle Benutzerverzeichnisse auf dem Computer auflisten. Normalerweise mache ich Folgendes:
ls -l /home
Aber ich verwende es in einem Skript, das auf anderen Computern bereitgestellt wird, und vielleicht auf diesen Computern, die sie nicht als "Zuhause" bezeichnen (z. B. myHome). Also möchte ich es verallgemeinern ls -l ~
. Es werden jedoch nur die Home-Verzeichnisse meiner Benutzer und nicht die Namen aller Home-Verzeichnisse der Benutzer aufgelistet (im Grunde möchte ich eine Liste der Benutzernamen auf dem Computer erhalten). Wie kann ich das verallgemeinern?
bash
shell-script
eval
Lakerda
quelle
quelle
~
im Allgemeinen das Äquivalent von/home/user
, nicht von/home
oder ist/home/*
(was Ihrer Absicht näher zu sein scheint).nobody
) ihr Home-Verzeichnis auf festgelegt/nonexistent
, was offensichtlich nicht vorhanden ist. (Für diese Benutzer ist natürlich auch der Kennwort-Hash*
und die Shell auf/usr/sbin/nologin
oder festgelegt/bin/false
, sodass sie sich zunächst nicht im normalen Sinne anmelden können.)Antworten:
Viele Systeme haben einen
getent
Befehl zur Liste oder fragen Sie den Inhalt der Name Service - Datenbanken wiepasswd
,group
,services
,protocols
...Würden Liste der Home - Verzeichnisse (die 6 th Kolon begrenzt Feld) alle Benutzer in Datenbanken, wird aufgezählt .
Der Benutzername selbst befindet sich im ersten Feld, also für die Liste der Benutzernamen:
(Beachten Sie, dass diese Benutzer sich nicht beim System anmelden können oder dass ihr Basisverzeichnis erstellt wurde. Sie sind dem System jedoch bekannt und können in eine Benutzer-ID übersetzt werden.)
Bei Datenbanken, die nicht aufgelistet werden können, können Sie versuchen, jede mögliche Benutzer-ID einzeln abzufragen:
(hier unter der Annahme, dass uids bei 65535 enden (einige Systeme unterstützen mehr) und eine Shell, die zshs
{x..y}
Form der Klammererweiterung unterstützt ). Auf Systemen, auf denen die Benutzerdatenbank vernetzt ist (und es nur begrenztes lokales Caching gibt), wie z. B. LDAP, NIS +, SQL ..., sollten Sie dies jedoch nicht häufig tun, da dies viel Netzwerkverkehr bedeuten und den Verzeichnisserver belasten kann ), um all diese Fragen zu stellen.Das bedeutet auch, dass Sie nur einen Eintrag für jede Benutzer-ID erhalten, wenn mehrere Benutzer dieselbe Benutzer-ID verwenden. Verpassen Sie also die anderen.
Wenn Sie nicht haben
getent
, können Sie auf Folgendes zurückgreifenperl
:für
getent passwd
($e[0]
für die Benutzernamen) oder:für
getent passwd {0..65535}
mit den gleichen einschränkungen.In Shells können Sie das Basisverzeichnis
~user
von abrufen. In denuser
meisten Shells funktioniert dies jedoch nur für einen begrenzten Satz von Benutzernamen (die Liste der zulässigen Zeichen in Benutzernamen, die für diesen~
Erweiterungsoperator unterstützt werden, variiert von Shell zu Shell) und mit Mehrere Shells (einschließlichbash
)~$user
funktionieren nicht (Sie müssten darauf zurückgreifeneval
wenn der Name des Benutzers in einer Variablen dort gespeichert ist). Und Sie müssen noch einen Weg finden, um die Liste der Benutzernamen zu erhalten.Einige Shells unterstützen diese Liste von Benutzernamen.
bash
:compgen -u
Gibt die Liste der Benutzer in Datenbanken zurück, die aufgelistet werden können.zsh
: Das$userdirs
assoziative Array ordnet Benutzernamen ihrem Ausgangsverzeichnis zu (auch beschränkt auf Datenbanken, die aufgelistet werden können. Wenn Sie jedoch eine~user
Erweiterung für einen Benutzer vornehmen, der sich in einer nicht aufzählbaren Datenbank befindet, wird ein Eintrag hinzugefügt$userdirs
). Sie können also Folgendes tun:um Benutzer mit ihrem Home-Verzeichnis aufzulisten.
Das funktioniert aber nur, wenn
zsh
es interaktiv ist .tcsh
,fish
undyash
sind drei weitere Shells, die Benutzernamen vervollständigen können (zum Beispiel beim Vervollständigen von~<Tab>
Argumenten), aber es sieht nicht so aus, als würden Sie diese Liste von Benutzernamen programmgesteuert erhalten.quelle
getent
es dort sein wird, was in gewissem Maße vom Umfang ihrer "anderen Maschinen" abhängt.perl
Alternative hinzugefügt .perl -le 'while (@e = getpwent) {print $e[7]}'
funktioniert gut unter macOS.getent passwd
zeigt Ihnen die Benutzerdatenbank. Das erste Feld ist der Benutzername, das sechste Feld ist das Ausgangsverzeichnis des Benutzers.Ein besserer Weg, um Benutzer-Home-Verzeichnisse aufzulisten, ist das Parsen
/etc/passwd
und von dort zu extrahieren und keine Vermutungen darüber anzustellen, wo sie sich befinden.Und Ihrem zweiten Kommentar nach zu urteilen, möchten Sie eigentlich die Benutzernamen und nicht deren Home-Verzeichnisse. In diesem Fall
/etc/passwd
ist dies ohnehin die bessere Wahl. Beachten Sie, dass auf einigen Linux- / UNIX-Computern andere Benutzerauthentifizierungsmechanismen konfiguriert sind (z. B. LDAP). Daher ist Ihre Abfrage letztendlich komplexer als Sie vielleicht zunächst glauben, aber/etc/passwd
ein guter Ausgangspunkt.quelle
getent
Systeme, die dies unterstützen.getent
ist immer besser als das Parsen/etc/passwd
(es geht um das Problem „anderer Benutzerauthentifizierungsmechanismen“).getent
Lösung ist, dass davon ausgegangen wird, dass die Datenquelle aufgezählt und nicht nur nach einem bestimmten Wert abgefragt werden kann. Das wird ausführlich in der Antwort von Stéphane Chazelas auf diese Frage beschrieben , aber ich würde trotzdem einen Kommentar für jeden hinzufügen, der über diese Seite blättert.Die kurze Antwort :
Die mittlere Antwort : Da Sie verwenden
bash
, können Sie alle möglichen Abschlüsse für die~
Verwendung auflistencompgen -A user
. Das ist so eine übliche Verwendung, es kann abgekürzt werdencompgen -u
. Hat als eingebaute Shellcompgen
keine eigene Manpage. Lesen Sie stattdessen die Dokumentation in Bash (1) und den Abschnitt über die programmierbare Vervollständigung .Eine gründlichere Alternative
Wenn Sie sich große Sorgen über die Portabilität machen, können Sie sich möglicherweise nicht einmal auf andere Computer verlassen
bash
. In diesem Fall machen Sie folgendes:Erläuterung Die lange Antwort versucht alles, sodass sie auf so ziemlich jedem UNIX-System funktioniert, unabhängig davon, ob die neuere Datei /etc/nsswitch.conf (mit der sowohl GNU / Linux als auch BSD geliefert werden
getent
) verwendet wird, die traditionelle UNIX-Passwd-Flat-Datei (MacOS) Directory Services¹ (dscl
) oder sogar die älteren MacOS X-Versionen mit Cat-Thema und NeXTSTEP (nidump
).Einfachheit Aber wie tragbar brauchen Sie? Unix hat viele Möglichkeiten, Dinge zu tun, und manchmal genügt einfacheres. Wenn Sie eine auswählen müssen, würde ich
getent passwd | cut -d: -f6
für Shell-Skripte empfehlenFußnote ¹: Ich habe MacOS schon länger nicht mehr benutzt. Wenn mir also jemand bestätigen kann, dass ich die richtige Syntax habe (und die Ausgabe keine Streukolons enthält, die das Ganze vermasseln würden
cut
), wäre das großartig. Vielen Dank.Fußnote ²: Was ich empfehle und was ich tue, kann abweichen. Persönlich verwende ich häufiger die traditionelle
cut -d: -f1 /etc/passwd
Befehlszeile. Nach Jahrzehnten der Wiederholung können meine Finger es tippen, während mein Verstand an anderen Dingen arbeitet.quelle
bash
hatcompgen -u
seit 2.04 im Jahr 2000 veröffentlicht worden.Was ist
ls -l ~/..
? Hier werden alle Verzeichnisse im übergeordneten Verzeichnis Ihres Basisverzeichnisses aufgelistet.quelle
/home
auf Linux-Systemen üblich ist, aber was passiert, wenn Sie das als ausführenroot
?). Das Auflisten von Home-Verzeichnissen ist ein Abenteuer voller Fallstricke, wenn Sie alle Fälle behandeln möchten, auf die Sie wahrscheinlich stoßen. Weitere Informationen finden Sie in den anderen Antworten.