Die Syntax a*und *a*wird von der Shell und nicht vom lsBefehl implementiert .
Wenn Sie tippen
ls a*
An der Shell-Eingabeaufforderung wird die Shell a*zu einer Liste aller im aktuellen Verzeichnis vorhandenen Dateien erweitert , deren Namen mit beginnen a. Beispielsweise kann es a*auf die Sequenz erweitert a1 a2 a3und diese als Argumente an übergeben werden ls. Der lsBefehl selbst sieht den *Charakter nie ; es sieht nur die drei Argumente a1, a2und a3.
Für die Platzhaltererweiterung bezieht sich "Dateien" auf alle Entitäten im aktuellen Verzeichnis. Dies kann beispielsweise a1eine normale Datei, a2ein Verzeichnis oder a3ein Symlink sein. Sie haben alle Verzeichniseinträge, und es ist der Platzhaltererweiterung der Shell egal, auf welche Art von Entität sich diese Einträge beziehen.
Praktisch alle Shells, auf die Sie wahrscheinlich stoßen (bash, sh, ksh, zsh, csh, tcsh, ...), implementieren Platzhalter. Die Details können variieren, aber die grundlegende Syntax des *Abgleichs von null oder mehr Zeichen und des ?Abgleichs eines einzelnen Zeichens ist einigermaßen konsistent.
Insbesondere für Bash ist dies im Abschnitt "Dateinamenerweiterung" des Bash-Handbuchs dokumentiert. starte info bashund suche nach "Dateinamenerweiterung", oder sieh hier .
Die Tatsache, dass dies von der Shell und nicht von einzelnen Befehlen ausgeführt wird, hat einige interessante (und manchmal überraschende) Konsequenzen. Das Beste daran ist, dass der Umgang mit Platzhaltern für (fast) alle Befehle konsistent ist . Wenn die Shell dies nicht tun würde, würden sich einige Befehle zwangsläufig nicht darum kümmern, und andere würden es auf subtile Weise tun, die der Autor für "besser" hielt. (Ich denke, die Windows-Befehlsshell hat dieses Problem, aber ich kenne es nicht gut genug, um weitere Kommentare abzugeben.)
Andererseits ist es schwierig, einen Befehl zum Umbenennen mehrerer Dateien zu schreiben. Wenn du schreibst:
mv *.log *.log.bak
Es wird wahrscheinlich fehlschlagen, da *.log.bakes basierend auf den Dateien, die bereits im aktuellen Verzeichnis vorhanden sind, erweitert wird. Es gibt Befehle, die so etwas tun, aber sie müssen ihre eigene Syntax verwenden, um anzugeben, wie die Dateien umbenannt werden sollen. Einige Befehle (z. B. find) können ihre eigene Platzhaltererweiterung ausführen . Sie müssen die Argumente angeben, um die Erweiterung der Shell zu unterdrücken:
find . -name '*.txt' -print
Die Platzhaltererweiterung der Shell basiert ausschließlich auf der Syntax des Befehlszeilenarguments und der Menge der vorhandenen Dateien. Es kann nicht durch die Bedeutung des Befehls beeinflusst werden. Wenn Sie beispielsweise alle .logDateien in das übergeordnete Verzeichnis verschieben möchten , können Sie Folgendes eingeben:
mv *.log ..
Wenn Sie das vergessen ..:
mv *.log
und es gibt zufällig genau zwei .logDateien im aktuellen Verzeichnis, es wird erweitert auf:
mv one.log two.log
die wird umbenennen one.logund clobber two.log.
EDIT : Und nach 52 Upvotes, einem Accept und einem Guru-Badge sollte ich vielleicht die Frage im Titel beantworten.
Die Option -doder sagt nicht, dass nur Verzeichnisse aufgelistet werden sollen. Es weist es an, Verzeichnisse nur als sich selbst aufzulisten, nicht als deren Inhalt. Wenn Sie einen Verzeichnisnamen als Argument angeben , wird standardmäßig der Inhalt des Verzeichnisses aufgelistet , da dies normalerweise für Sie von Interesse ist. Mit dieser Option wird festgelegt, dass nur das Verzeichnis selbst aufgelistet wird. Dies kann insbesondere in Kombination mit Platzhaltern hilfreich sein. Wenn Sie Folgendes eingeben:--directorylsls-d
ls -l a*
lsSie erhalten eine lange Liste aller Dateien, deren Name mit "" beginnt a, sowie der Inhalte aller Verzeichnisse, deren Name mit "" beginnt a. Wenn Sie nur eine Liste der Dateien und Verzeichnisse mit jeweils einer Zeile benötigen, können Sie Folgendes verwenden:
ls -ld a*
was äquivalent ist zu:
ls -l -d a*
Denken Sie erneut daran, dass der lsBefehl das *Zeichen nie sieht .
Wo dies dokumentiert ist, man lszeigt Ihnen die Dokumentation für den lsBefehl auf nahezu jedem Unix-ähnlichen System. Auf den meisten Linux-basierten Systemen ist der lsBefehl Teil des GNU-Pakets coreutils. wenn Sie die haben infoBefehl, entweder info lsoder info coreutils lssollten Sie mehr endgültige und umfassende Dokumentation geben. Andere Systeme, wie z. B. MacOS, verwenden möglicherweise andere Versionen des lsBefehls und verfügen möglicherweise nicht über den infoBefehl. Verwenden Sie für diese Systeme man ls. Und ls --helpzeigt eine relativ kurze Verwendungsmeldung (117 Zeilen auf meinem System), wenn Sie die GNU-Coreutils-Implementierung verwenden.
Und ja, auch Experten müssen ab und zu die Dokumentation konsultieren. Siehe auch diesen klassischen Witz .