Der Befehl 'ls -d' zeigt keine Verzeichnisse an. Gibt es eine Möglichkeit, mit 'ls' nur Verzeichnisse anstelle von Dateien und Verzeichnissen anzuzeigen?

44

Gibt es eine Möglichkeit, lsnur Verzeichnisse anstelle von Dateien und Verzeichnissen anzuzeigen?

Von der Manpage:

   -d, --directory
          list directory entries instead of contents, and do not  derefer
          ence symbolic links

Wenn ich es also in das /Verzeichnis eingebe, werden voraussichtlich nur Verzeichnisse angezeigt. Stattdessen wird "." Angezeigt.

$ cd /
$ ls -d
.

Ich hatte erwartet ls -d, mir das zu zeigen:

$ ls -d
bin    data  home        opt    sbin  sys      var
boot   dev   lib         media  proc  selinux  tmp
cdrom  etc   lost+found  mnt    root  srv      usr

Gibt es eine Möglichkeit, lsnur Verzeichnisse anstelle von Dateien und Verzeichnissen anzuzeigen?

Nelaaro
quelle
17
lsd kann sehr verwirrend sein.
Boehj
2
@ jin ls -d * / works. Aber warum muss ich "* /", um die gewünschte Ausgabe zu erhalten?
Nelaaro
8
@nelaar -dbedeutet nicht, nur Verzeichnisse aufzulisten , sondern nicht, den Verzeichnisinhalt aufzulisten . Wenn ls */Sie versuchen, etwas einzugeben, sehen Sie den Inhalt aller Verzeichnisse.
Jin
2
Ich habe ldirmich ls -d */in meinem verbündet, .bashrcum dies einfacher zu machen ...
DQdlM
1
Sie können Ihnen
jede Menge

Antworten:

50

Ihre Erwartungen basieren auf DOS Think / Windows Think und sind falsch. Unter MS-DOS, Windows und in der Tat einigen anderen IBM / Microsoft-Betriebssystemen wird die Platzhaltererweiterung vom Befehl selbst ausgeführt, und Dinge wie die /aOption zum dirBefehl wirken als Attributfilter während der Platzhaltererweiterung. dirErweitert Platzhalter wie *, die der Befehlsinterpreter unverändert weitergibt, und /awendet bei Angabe die entsprechenden Filter auf die zurückgegebenen Werte an. (Bei einigen Betriebssystemen können die Attributfilter dem Systemaufruf zum Auflisten eines Verzeichnisses zugewiesen werden, und der Betriebssystemkernel oder seine Dateisystemtreiber wenden sie selbst an.)

Unter Unices und Linux wird die Platzhaltererweiterung von der Shell ausgeführt, und Berechtigungen werden nicht berücksichtigt. Wenn Sie dies im Stammverzeichnis tun

ls *

was der lsBefehl selbst von der Shell erhält, ist (so etwas wie)

ls bin zu Hause opt var boot dev tmp etc verloren + gefunden root usr

Mit der Option -d/ --directorywird deaktiviert, was normalerweise als Nächstes passiert . Was normalerweise als nächstes passiert, ist, dass lsjedes Argument der Reihe nach überprüft wird, dass es sich um Verzeichnisse handelt, und entschieden wird, deren Inhalt aufzulisten. Bei Argumenten, die Dateien benennen, werden nur die Informationen für die Datei selbst ausgedruckt. Mit dieser -dOption werden Verzeichnisse wie Dateien behandelt. So lsdruckt die Informationen für jedes der Verzeichnisse aus , die als Argumente übergeben wird, so wie es tun würde , wenn sie Dateien sind.

Es -d ist also keine Option "Nur Verzeichnisse drucken". Tatsächlich gibt es nicht nur keine solche Option; Es kann keine solche Option geben. Die Platzhaltererweiterung wird von der Shell durchgeführt, und ( shzumindest unter POSIX ) kann die Shell nicht angewiesen werden, die Berechtigungs- und Dateitypbits zu überprüfen, wenn sie *in eine Liste von Namen erweitert wird. Um nur eine Liste der Verzeichnisnamen zu erhalten, müssen Sie entweder den findBefehl verwenden, wie unter erläutert ztank1013, oder den Trick anwenden, dass ein mit einem Schrägstrich endender Pfadname den Verzeichniseintrag impliziert ., wie unter erläutert Jin. ( Jins Trick endet damit, dass der lsBefehl die Argumente empfängt

ls bin / home / opt / var / boot / dev / tmp / etc / lost + found / root / usr /

weil das Muster */tatsächlich Pfadnamen mit zwei Komponenten vergleicht, wobei die zweite leer ist und daher nicht genau das tut, was gewünscht wurde. Insbesondere werden symbolische Links, die auf Verzeichnisse verweisen, so behandelt, als wären sie Verzeichnisse.)

Das Verhalten von ls -dohne *ist eine einfache Erweiterung des oben Gesagten. Man muss nur noch eines wissen ls: Wenn es keine Argumente gibt, nimmt es ein Standardargument von an .. Nun , ohne die -dMöglichkeit, die oben genannte Verhalten führt zu dem Inhalt des Verzeichnisses mit dem Namen von .aufgezählt werden und die Informationen für seinen Inhalt angezeigt. Mit dieser -dOption wird das Verzeichnis .so behandelt, als ob es eine Datei wäre, und es werden statt des aufgezählten Inhalts seine eigenen Informationen angezeigt.

JdeBP
quelle
3
"Es kann keine solche Option geben" - das ist eine ziemlich starke Aussage - die Implementierung einer solchen Option ist offensichtlich: Sehen Sie sich ein Nicht-Verzeichnis-Argument an und ignorieren Sie es. Was nicht implementiert werden kann, ist das Äquivalent von dir /s *.txt[ohne Platzhalter für find]
Random832
6
Richtig, aber es gibt keinen logischen Grund ls kann nicht über eine Option, die Einzelteile herauszufiltern , die in als Argumente übergeben wurden. Die Tatsache , dass „Wildcard - Erweiterung vom Eintrag Typprüfung ist geschieden“ ist irrelevant, da das hat nichts überhaupt mit Wildcard - Erweiterung zu tun - nur Eintrag Typprüfung, die es keinen Grund gibt es nicht getan werden kann vollständig innerhalb ls. Wenn ls --color sie blau schattieren kann, ls -F ein / nach ihnen setzen kann und ls -l ein 'd' in den Modus setzen kann, dann könnte eine andere hypothetische Option sie weglassen. Dass es eine solche Option nicht gibt, heißt nicht, dass sie " nicht kann ".
Random832
5
Random832 macht einen anständigen Punkt: Es ls könnte eine Option zum Filtern von Dateien oder Verzeichnissen geben, und dies schließt sich nicht gegenseitig aus, wenn die Shell eine Erweiterung vornimmt . Es gibt keine Racebedingung in ls: Es kann gefiltert werden, da es die Dateien normal angibt. (Es gibt bereits einen Wettlauf zwischen der Shell-Erweiterung und ls, FWIW.) Ich denke, die Shell-Erweiterung ist nur ein Teil des Grundes: Die Shell-Erweiterung (und das Filtern im Allgemeinen) ist in ls nicht implementiert, da sie in cp erneut implementiert werden müsste , mv, etc. Unix ist ein "mach eins und mach es gut". Wenn Sie eine erweiterte Filterung benötigen, gibt es Tools dafür.
Thanatos
2
Die ls -pOption fügt /nur Verzeichnissen ein Symbol hinzu . Es gibt keinen Grund, die Ausgabedruckfunktionen nicht um etwas zu erweitern, das nur diese (anstatt ls -p | grep /) ausgibt .
Anne van Rossum
3
@JdeBP, Ad-Hominem-Angriffe ("kiddo") und Arroganz (alle außer Ihnen kennen "die Grundlagen von Unix" nicht) gehören nicht zu einer technischen Diskussion. Außerdem ziehen Sie einen Strohmann, wenn Sie argumentieren, dass eine Befehlsoption die Platzhaltererweiterung durch Shell nicht steuern kann. Natürlich kann es nicht! Weder Random832 noch Thanatos noch Anne van Rossum und nicht einmal die Frage selbst erwähnen in irgendeiner Weise Wildcards. Der Einwand war, dass diese ls --only-directories .Option eventuell ergänzt werden könnte ls.
mkalkov
30

Sie können ls -d */oder ls -d .*/für versteckte Verzeichnisse verwenden.

Jin
quelle
cleverer Trick mit dem /!
Mono
Ja das ist gut. Gibt es einen Fall, in dem dies nicht funktioniert?
iyrin,
5
+1 für die Angabe der Antwort in einer Zeile. Ich schätze, die akzeptierte Antwort hat sie auch irgendwo.
Calculus Knight
Wie können Sie dies in einem Skript verwenden, ohne sich bereits im Verzeichnis zu befinden?
DimiDak
13

Versuche dies

 find . -mindepth 1 -maxdepth 1 -type d

um nur Verzeichnisse unter Ihrem aktuellen Standort abzurufen.

ztank1013
quelle
5

Das könnte dir auch gefallen

tree -d 

Hier werden alle Verzeichnisse und Unterverzeichnisse mit einer grafischen Darstellung der Baumstruktur übersichtlich aufgelistet.

fuenfundachtzig
quelle
3
Und nur für eine Ebene tief:tree -dL 1
Anne van Rossum
Leider kann man nicht viel mit Baum kombinieren. # tree -d | grep wc -l (Standardeingabe)
DimiDak
5

Wenn Sie Verzeichnisse nur mit der ls -lOption (ELL) anzeigen möchten, können Sie Folgendes verwenden:

find -maxdepth 1 -type d -ls;

Oben finden Sie nur die Details, die Sie mit der -lOption erhalten.

Adnan Bhatti
quelle
1
Möglicherweise ist es sogar besser, die find -maxdepth 1 -type d -exec ls -d {} +Ausgabe im üblichen lsFormat zu erhalten.
mkalkov
4

Wenn Sie den Job auf andere Weise erledigen möchten, versuchen Sie Folgendes:

ls -l | grep ^d

Obwohl ein einziges Werkzeug in dieser Situation ausreicht. Die Rohrleitung ist immer da, um Ihnen zu helfen. Mir gefällt die Flexibilität in Linux, die Sie wünschen.

Bohr
quelle
1
Dies wird mehr als nur Verzeichnisse herausfiltern.
ocodo
2
@ Slomojo, dies wird alles außer Verzeichnissen herausfiltern. Was hast du gemeint?
mkalkov
Ja, Sie brauchen das -l (lang), damit die Berechtigungen die ganze Zeile durchgehen. "d" für Verzeichnis. Außerdem erhalten Sie eine "lange" Auflistung eines Verzeichniseintrags, was nett ist.
GeoO
1

Ich hoffe, dass dies Ihr Bedürfnis behebt. Der folgende Befehl listet nur Verzeichnisse in einem bestimmten Pfad auf.

ls -F <path> | grep /

Beispiel:

ls -F ~ | grep /
Thiyagu ATR
quelle