Ich möchte testen, ob ein relativer Symlink auf den Teilbaum eines bestimmten Verzeichnisses verweist.
Dieses Beispiel würde ergeben, false
da es außerhalb des foo
Verzeichnisses zeigt:
/foo>readlink bar
../fie.txt
Während dieses Beispiel ergeben würde true
:
/foo>readlink bar
fum/fie.txt
Gibt es ein vorhandenes Dienstprogramm, das ich nutzen kann, oder muss ich es von Grund auf neu codieren? Ich benutze bash
.
fie.txt
oderfum
ist es selbst ein Symlink außerhalbfoo
?/foo
oder müssen Sie in der Lage sein, beliebige Verzeichnisse zu übergeben? Ich meine, ist die Frage immer in Bezug auf./
oder nicht?Antworten:
Ich glaube nicht, dass es so ein Dienstprogramm gibt. Mit GNU
readlink
können Sie Folgendes tun:Dadurch werden alle Symlinks aufgelöst, sodass ein kanonischer absoluter Pfad für Nadel und Heuhaufen entsteht.
Erläuterung
-e
statt-f
, um sicherzustellen, dass die Dateien vorhanden sind. Die-v
Option gibt eine Fehlermeldung aus, wenn auf die Dateien nicht zugegriffen werden kann.--
sollte verwendet werden, um das Ende von Optionen und Anführungszeichen zu markieren, da wir hier nicht den Operator split + glob aufrufen möchten./foo<LF><LF>
,$(readlink -ve -- "$1")
zurückkehren würde/foo
. Die übliche Problemumgehung besteht darin, ein Nicht-LF-Zeichen (hier.
) anzuhängen und dieses und das zusätzliche LF-Zeichen, das mit hinzugefügt wurde,readlink
zuvar=${var%??}
entfernen (entfernen Sie die letzten beiden Zeichen).Die Nadel gilt als im Heuhaufen, wenn es sich um den Heuhaufen handelt oder wenn es sich um einen Heuhaufen handelt. Das würde jedoch nicht funktionieren, wenn der Heuhaufen wäre
/
(/etc
denn stattdessen nicht//something
)./
muss oft speziell behandelt werden, denn während/
und/xx
mit der gleichen Anzahl von Schrägstrichen, ist einer eine Ebene über dem anderen.Eine Möglichkeit, dies zu beheben, besteht darin, es
/
durch die leere Zeichenfolge zu ersetzen, mit der fertig istvar=${var%/}
(der einzige Pfad, der damit endet/
,readlink -e
ist/
, dass das Entfernen eines nachgestellten/
Zeichens/
in die leere Zeichenfolge geändert wird ).Für die Kanonisierung der Dateipfade können Sie eine Hilfsfunktion verwenden.
quelle
needle=${needle%??} haystack=${haystack%??}
derneedle
Variablen zuerst behandelt wird, während es in der nächsten Zeile umgekehrt ist? Wie kommt es, dass Ihrereturn
Anweisungen nicht explizit einen Wert ungleich Null zurückgeben (um einen Fehler anzuzeigen)? Letzteres: Wäre es sinnvoll, die gesamte Transformation (den Aufruf vonreadlink
plus die beiden Suffix-Kürzungen) in eine separate_canonicalize_path
Hilfsfunktion zu zerlegen?return
gibt standardmäßig den Status des letzten Befehls zurück. Mit|| return
können Sie den Status zurückgeben, der von der fehlgeschlagenen Anwendung bereitgestellt wird. 3) sicher, aber die resultierende Funktion wird wahrscheinlich kein angenehmer Anblick sein. Ich werde ein Beispiel hinzufügen.Ich habe das Problem folgendermaßen gelöst:
echo $abs_link_target | grep -qe "^$containing_dir"
Die
$abs_link_target
Variable enthält den absoluten Pfad zum Symlink-Ziel (erweitert durchreadlink -f
). Ich überprüfe dann, ob der Anfang des Zielpfads mit dem Anfang des übereinstimmt$containing_dir
quelle
$containing_dir
als regulärer Ausdruck genommen)/foo<LF>/abc
(die Linien der Musterzeichenfolge werden als unterschiedliche Muster behandelt, um übereinzustimmen)/foo<LF>/abc
in/abc
(grep
Übereinstimmungen in jeder Zeile der Eingabe, nicht die gesamte Eingabe, daher kann im Allgemeinen nicht zum Abgleichen von Dateinamen verwendet werden).echo
Implementierung und / oder der Umgebung sollten Sie Probleme mit Dateinamen haben, die Backslashes enthalten. Sieecho
sollten wirklich nicht für den Umgang mit beliebigen Daten verwendet werdengrep -q "^/foo/bar/" <<< "$(readlink -f "anyfile.ext")"
quelle
anyfile.ext
existiert und ist erreichbar (ansonstenreadlink -f
im Gegensatz zureadlink -e
Macht nicht geben Sie den richtigen Pfad) , und dass der resultierende Pfad Zeilenumbrüche enthält keine ( übernimmt zsh oder bash4 oder ksh93m + oder höher). Beachten Sie, dass wenn esanyfile.ext
auf sich/foo/bar
selbst zeigt, es sagt, dass es nicht innerhalb ist.