Ich habe ein Skript, das rekursiv symbolische Links in meinem Home-Verzeichnis zu meinem Einstellungsverzeichnis erstellt, um die Dateien unter Versionskontrolle zu halten. Ich möchte, dass es Dateien überspringt, die bereits über ein übergeordnetes Verzeichnis symbolisch verknüpft sind. Das heißt, wenn ich diese Dateien/Verzeichnisse habe:
~/foo/ -> ~/settings/foo/
~/settings/foo/
~/settings/foo/bar
, wie überprüfe ich, ob ~/foo/bar und ~/settings/foo/bar dieselbe Datei sind?
Bearbeiten: D'oh, ein paar weitere Minuten der Suche ergaben dieAntwort:readlink -f $path
Antwort1
Wenn zwei Dateien dieselbe Geräte-ID und denselben Inode haben, handelt es sich um dieselbe Datei. Mit dem stat
Befehlszeilentool lässt sich dies leicht herausfinden, und diese Lösung ist POSIX-Shell-kompatibel.
if [ "$(stat -L -c %d:%i FILE1)" = "$(stat -L -c %d:%i FILE2)" ]; then
echo "FILE1 and FILE2 refer to a single file, with one inode, on one device."
else
echo "no match"
fi
Das -L
Flag in jedem stat
bedeutet, dass dies sowohl für symbolisch verknüpfte als auch für fest verknüpfte Dateien funktioniert.
Antwort2
Viele Shells haben einen -ef
Operator für das test
Builtin (oder sein Synonym [
), um zu testen, ob zwei Pfade auf dasdieselbe vorhandene Datei(symbolischen Links folgen). Dies umfasst bash, dash, pdksh, ksh88, ksh93 und zsh, aber nicht POSIX sh. In bash, ksh oder zsh können Sie auch -ef
die [[ … ]]
bedingte Konstruktion verwenden.
if ! [ "$1" -ef "$2" ]; then # $1 and $2 are different files
Antwort3
Für Softlinks (erstellt mit ln -s
) können Sie verwenden realpath
. Für Hardlinks funktioniert das allerdings nicht.