Ich habe folgenden Verzeichnisbaum:
.
└── aaa
└── bbb
└── ccc
Und erstellen Sie einen symbolischen Link:
ln -s ~/test/aaa/bbb slink
Danach führe ich den Tree-Befehl aus:
tree -l
und sehen
.
├── aaa
│ └── bbb
│ └── ccc
└── slink -> /home/kaa/test/aaa/bbb [recursive, not followed]
Warum wird Slink als rekursiv markiert? Ist das ein Fehler oder verstehe ich etwas falsch?
Antwort1
Sie haben die -l
Option genutzt:
Folgt symbolischen Links, wenn sie auf Verzeichnisse verweisen, als wären sie Verzeichnisse. Symbolische Links, die zu einer Rekursion führen, werden vermieden, wenn sie erkannt werden.
Der Grund für diese Warnung ist nicht, dass sieGenau genommenrekursiv. Wir können deutlich sehen, dass es den bbb/ccc
Baum einfach erneut auflisten würde.
Der jeweilige Code lautetHier, übrigens. Wenn die Inode-Nummer des Verzeichnisses, auf das der Symlink zeigt, in der Hash-Tabelle gefunden wird (die mit saveino
und gefüllt ist findino
), wird sie einfach übersprungen.
Antwort2
Ich denke, die Dokumentation ist ungenau. In der Dokumentation steht
Symbolische Links, die zuRekursionwerden vermieden, wenn sie erkannt werden
aber es sollte etwas sagen wie
Symbolische Links, die zuein bereits besuchtes Verzeichniswerden nicht befolgt
SehenOrt der Fehlermeldung intree.c
Und
Funktion findino
inhash.c
.
tree -l
merkt sich besuchte Verzeichnisse und wechselt nur inLinksderen Ziel noch nicht besucht wurde:
( mkdir test1 && cd test1 && mkdir -p a/b && ln -s a link && tree -l; )
.
├── a
│ └── b
└── link -> a [recursive, not followed]
Beachten Sie, dass das Ignorieren bereits besuchter Verzeichnisse nur erfolgt fürLinks.RealVerzeichnisse werden immer besucht. Das bedeutet, dassDie Reihenfolge der Durchquerung ist wichtig. Das Durchlaufen genau desselben Baums in umgekehrter alphabetischer Reihenfolge ( -r
) folgt dem Link, da es den Link zu einem Zeitpunkt besucht, an dem sein Ziel noch nicht besucht ist.
( cd test1 && tree -r -l; )
.
├── link -> a
│ └── b
└── a
└── b
Hier sind zwei weitere Alternativen, um dieses Verhalten zu reproduzieren:
Ignoriere -I
das Verzeichnis () a/
, damit es beim Besuch des Links nicht besucht wird:
( cd test1 && tree -l -I a; )
.
└── link -> a
└── b
Benennen Sie die Verzeichnisse und den Link, sodass der Link automatisch zuerst besucht wird:
( mkdir test2 && cd test2 && mkdir -p x/y && ln -s x link && tree -l; )
.
├── link -> x
│ └── y
└── x
└── y