Was sind ./ und ../ Verzeichnisse?

20

Einfache Frage, aber ich bin nicht sicher, wo ich suchen soll, und Google reagiert nicht auf Punkte und Schrägstriche.

Ich habe nur versucht, die Anzahl der Dateien und Verzeichnisse im aktuellen Verzeichnis zu zählen (ohne Unterordner / Dateien) und habe versucht, zu unterscheiden, ls -1 | wc -lund ls | wc -lda sie identisch zu sein scheinen. Eine Site, die ich mir ansah, sagte: "Denken Sie daran, dass dies auch die Verzeichnisse ./ und ../ zählt." in Bezug auf die mit ls -1, und ich bin nicht sicher, ob das bedeutet, dass es die Verzeichnisse vor oder etwas enthält (was ich nicht möchte), aber es schien nicht zu tun, dass aus dem Testen.

Könnte jemand bestätigen, welches der Verzeichnisse am besten geeignet ist, um die Anzahl der Dateien und Verzeichnisse im aktuellen Verzeichnis (nicht im Unterverzeichnis) zu zählen, und was sie mit ./ und ../ Verzeichnissen bedeuten?

Adam
quelle
Die
Meldung

Antworten:

15

Jedes Verzeichnis auf einem Unix-System (und wahrscheinlich auch jedes andere System) enthält mindestens zwei Verzeichniseinträge. Dies sind .(aktuelles Verzeichnis) und ..(übergeordnetes Verzeichnis). Im Fall des Stammverzeichnisses verweisen diese auf dieselbe Stelle, bei allen anderen Verzeichnissen sind sie jedoch unterschiedlich. Sie können dies mit den Befehlen stat, pwdund cd(unter Linux) überprüfen:

$ cd /
$ stat . .. bin sbin | grep Inode
Device: 802h/2050d      Inode: 2           Links: 27
Device: 802h/2050d      Inode: 2           Links: 27
Device: 802h/2050d      Inode: 548865      Links: 2
Device: 802h/2050d      Inode: 2670593     Links: 2
$ pwd
/
$ cd ..
$ pwd
/
$

Beachten Sie, dass binund sbinjeder hat zwei Links dazu. Einer ist der Verzeichniseintrag im Stammverzeichnis und der andere ist der .Eintrag in diesem Verzeichnis.

Die Verwendung lsmit einer Pipe to wc -list ein einfacher Trick, um die Anzahl der Zeilen in der Ausgabe von ls zu zählen. Die Annahme ist, dass jede Datei oder jedes Verzeichnis genau eine Zeile in der Ausgabe belegt. GNU ls wird dies automatisch tun, wenn der Ausgang kein Terminal ist. Andere benötigen möglicherweise die -1Option, um das Verhalten explizit zu aktivieren. wc -lZählt einfach die Anzahl der Zeilen ( -l) in seiner Eingabe und gibt sie aus .

Das Problem bei diesem Ansatz ist, dass in Linux und in den traditionell unter Linux verwendeten Dateisystemen Datei- und Verzeichnisnamen (in dieser Hinsicht sind sie wirklich identisch) Zeilenumbrüche enthalten dürfen . Bei Vorhandensein dieser Einträge fällt jede Methode auseinander - diese Einträge werden als zwei oder mehr Einträge gezählt, wenn sie in Wirklichkeit eins sind.

Solange Sie GNU ls verwenden, haben keine Verzeichniseinträge mit Namen Zeilenumbrüche enthalten, und haben keine ungeradeen Aliase für ls(zum Beispiel ls -a), werden beide Ausgänge die Anzahl der Dateien und Verzeichnisse im aktuellen (oder angegebenen) Verzeichnis. Für die meisten Menschen ist das gut genug, aber im allgemeinen Fall nicht gültig .

Wenn Sie ungewöhnliche Zeichen (hauptsächlich Zeilenumbrüche) in Verzeichniseintragsnamen richtig behandeln müssen, schlage ich vor, die -bOption ls zu verwenden , um sie zu maskieren . ls -1bAGibt den Namen jedes Verzeichniseintrags in einer eigenen Zeile aus, wobei ungewöhnliche Zeichen (dh jeder Verzeichniseintrag wird als ein einziger angezeigt), einschließlich aller Punktdateien und -verzeichnisse, ausgeblendet werden. Wenden Sie sich an, wc -lum eine vollständige Befehlszeile zu erhalten, ls -1bA | wc -ldie die Anzahl der Dateien und Verzeichnisse im aktuellen Verzeichnis angibt (aber ignorieren Sie .und ..; das ist der Unterschied zwischen -aund -A), aber nicht in Unterverzeichnisse absteigend. Wenn Sie nicht möchten, dass Dotfiles zur Gesamtsumme gezählt werden, lassen Sie den -AParameter einfach weg ls.

ein CVn
quelle
Beides -aund -Aauch versteckte Dateien, von denen ich erkannt habe, dass ich sie vermeiden möchte. Das würde ich höchstens tun ls -b | wc -l, aber das gibt mir die richtige Antwort. Ist die Zeile, die ich in Bezug auf diesen Befehl kopiere und einfüge, falsch? Wenn es richtig war, sollte ich dann nicht eine Ausgabe von 8 erhalten, wenn sich 6 Dateien oder Ordner in einem Verzeichnis befinden?
Adam
@Adam ja, das wird wahrscheinlich den Trick machen ("ls -b | wc -l"); Sie können auch "-1" (Bindestrich + Nummer eins) verwenden, um eine Auflistung in einer einzelnen Spalte statt in allen Zeilen zu erzwingen. Dies geschieht jedoch trotzdem, wenn Sie zu einem anderen Befehl weiterleiten. Also (imho) würde ich es als "ls -1b | wc -l" belassen; und um "zu testen", führe "ls -1b" aus und zähle die Anzahl der Zeilen, dann führe "ls -1b | wc -l" aus und überprüfe die Ergebnisse. (So ​​debuggen / testen Sie Pipes.)
Michael
@Sardathrion, diese FAQ ist ziemlich irreführend. Die Konventionen des Unix-Dateisystems sind nicht "seltsam". Wo sie üblich sind , holt sie das andere System ab. Aber ok. Dann heißt es, dass der Befehl "file" magische Zahlen verwendet, um ... zu identifizieren, was falsch ist: Er verwendet auch viele Heuristiken. In meinem Buch nicht sehr zuverlässig.
vonbrand
@vonbrand: fair genug, link gelöscht. Ich habe es nur überflogen und es schien in Ordnung zu sein. Ich weiß, ich habe eine gefunden, die gut war, kann mich aber jetzt nicht erinnern, wo sie war.
Sardathrion - Wiedereinsetzung von Monica am
1
Du liegst falsch: . und .. sind historische Artefakte von UNIX in den 1970er Jahren und stammen aus einer Zeit, als es noch keinen mkdir()Systemaufruf gab. Nicht alle Dateisysteme haben sie und sie werden von POSIX nicht einmal benötigt oder benötigt.
Schily
6

So beantworten Sie die Frage im Betreff:

Wenn ein Verzeichnis B in Unix erstellt wird, wird er als neuer Eintrag in ein anderes Verzeichnis A (das übergeordnete Verzeichnis) und in B hinzugefügt werden zwei Einträge hinzugefügt: one bezeichnet .als feste Verbindung zu sich selbst, und man bezeichnet ..als Fest Link zu A.

Dies sind die einzigen festen Links zu Verzeichnissen, die zulässig sind (obwohl einige ältere Versionen einiger Unices auch beliebige Links zuließen).

Aus diesem Grund gibt bei den meisten Dateisystemen ( btrfseine bemerkenswerte Ausnahme) die Nummer linkseines Verzeichnisses an, über wie viele Unterverzeichnisse es verfügt (wobei deren ..Einträge berücksichtigt werden ).

Wenn Sie ein Verzeichnis umbenennen / verschieben und es sich in demselben Verzeichnis befindet (unter einem anderen Namen), wird nur der Namenseintrag in Ageändert. B .und ..ist nicht betroffen. Aber wenn Sie sich bewegen es tun ein anderes Verzeichnis, dann ..in Bwird sich ändern. Das erklärt, warum Sie ein Verzeichnis, auf das Sie keinen Schreibzugriff haben (vorausgesetzt, Sie haben Schreibzugriff auf das übergeordnete Verzeichnis), nur umbenennen können, solange Sie es nicht in ein anderes Verzeichnis verschieben (andernfalls verhindert die Notwendigkeit, den ..Eintrag zu ändern) Sie davon ab, es zu bewegen).

Beachten Sie jedoch: /a/b/../cvielleicht nicht das gleiche wie sein , /a/cda /a/bkönnte eine sein symbolischer Link zu einem anderen Verzeichnis.

Eine Ausnahme ist, wenn dieser Pfad dem cdBefehl für einige Shells zugewiesen wird. Diese cdbehandeln es .. logisch , die ..Einträge in Verzeichnissen zu ignorieren . Ein Grund, warum Sie cd -Pin ordnungsgemäß geschriebenen Skripten häufig feststellen, dass diese Funktion deaktiviert werden muss, da dies sonst zu Verwirrung und Inkonsistenzen führen kann.

Um die Anzahl der Einträge im aktuellen Verzeichnis ohne .und ..mit zu zählen bash, können Sie Folgendes tun:

shopt -s nullglob dotglob
set -- *
echo "$#"

Mit zsh:

f=(*(ND))
echo $#f

Tragbar:

find . ! -name . -prune -print | grep -c /
Stéphane Chazelas
quelle
Ich bin ein wenig verwirrt; Alle drei von Ihnen aufgelisteten Werte erhöhen die tatsächliche Anzahl um eins. zB wenn ich 6 Dateien oder Ordner in einem Verzeichnis, sie Ausgang 7, 6 nicht zu mir, wie es scheint , ls | wc -list der einzige Ausnahme .und..
Adam
1
@Adam lslistet keine versteckten Dateien auf. Sie müssen ls -Adas gleiche wie diese bekommen. WENN Sie die versteckten Dateien nicht zählen möchten, entfernen Sie das dotglob(für Bash) oder D(für Zsh) oder fügen Sie ein ! -name '.*'Vorher -printfür hinzu find.
Stéphane Chazelas
Ja, ich habe das erst bemerkt, nachdem ich die Dateien tatsächlich aufgelistet habe. Weißt du dann, warum ls | wc -lich immer noch die richtige Antwort gebe und versteckte Dateien ausschließt, .& ..?
Adam
1
Adam, in Ihrem Verzeichnis, Sie haben ., ..und eine andere Datei , deren Name beginnt mit .dem nicht durch ls aufgeführt , aber wäre durch ls -A. So ls | wc -lerhalten Sie nicht die richtige Antwort , weil es nicht , dass die versteckte Datei zu zählen.
Stéphane Chazelas
1
Ja, .und ..sind versteckte Dateien, da sie mit einem beginnen .. Es gibt sogar eine Legende, die erklärt, dass Punktedateien versehentlich ausgeblendet werden, da eine frühe Implementierung von lsnur .und ausschließen sollte .., aber es gab einen Fehler, der dazu führte, dass alle Dateien, die mit beginnen, ausgeschlossen wurden .. ls | wc -lfunktioniert nicht, wenn Dateinamen Zeilenumbrüche enthalten.
Stéphane Chazelas
1

Ich bin kein großer Linux-Experte, aber ich kenne Linux (war vor 16 Jahren Administrator bei Slackware :), gute alte Zeit

In den Verzeichnissen ./ und ../ ist es ganz einfach:. ist aktuelles Verzeichnis, .. ist vorheriges Verzeichnis (im Baum von pwd -local directory command-

Wenn es sie zählt, rechne ich damit, dass sie 2 zur Gesamtsumme der Auflistung addieren, nicht wirklich rekursiv gehen und das Verzeichnis unter dem aktuellen zählen und auch das aktuelle Verzeichnis (.) Noch einmal zählen :))

Grundsätzlich denke ich, dass es den Wert 2 hinzufügt, um bereits (Dateien) im aktuellen Verzeichnis zu zählen.

Wer korrigiert mich, wenn ich falsch liege?

Ich poste nur um zu helfen und sehe, dass niemand diese Frage hier beantwortet hat, sie könnten beschäftigt sein. Aber experimentieren Sie einfach und sehen Sie, ob Sie 10 Dateien haben und die Anzahl von 12 erhalten, dann ist es das.

Adrian Tanase
quelle
Ja, Adrian ist richtig:. ist das aktuelle Verzeichnis und .. ist das Verzeichnis direkt über der Hierarchie.
Schaiba
.. verweist nicht immer auf das vorherige Verzeichnis im Baum: in "/" .. verweist auch auf das aktuelle Verzeichnis.
Bonsi Scott
weil du vielleicht im / root des Dateisystems bist?
Adrian Tanase
Wenn es zwei Dateien zu der Anzahl der Dateien in einem Verzeichnis hinzufügt, warum erhalte ich dann die richtige Antwort, wenn ich es in Terminal auf OSX teste? Beispiel: Ein Verzeichnis mit 6 Dateien oder Ordnern gibt 6 und nicht 8 aus, wenn ich das tuels | wc -1
Adam,
Ich erkennen , dass es ist , weil sie mit versteckten Dateien sind (nämlich .DS_Store), aber ich sehe noch nicht , wie ls | wc -lumfasst .und , ..wenn ich die richtige Antwort, in Bezug auf die richtige Antwort im Gegensatz + 2.
Adams