it-swarm.com.de

Feststellen, ob eine Datei ein fester oder ein symbolischer Link ist?

Ich erstelle ein Shell-Skript, das einen Dateinamen/Pfad zu einer Datei verwendet und feststellt, ob es sich bei der Datei um eine symbolische Verknüpfung oder eine feste Verknüpfung handelt.

Das einzige ist, ich weiß nicht, wie ich sehen soll, ob es sich um eine harte Verbindung handelt. Ich habe 2 Dateien erstellt, eine feste Verknüpfung und eine symbolische Verknüpfung, um sie als Testdatei zu verwenden. Aber wie würde ich feststellen, ob eine Datei ein fester Link oder ein Symbol in einem Shell-Skript ist?

Wie würde ich auch die Zielpartition eines symbolischen Links finden? Angenommen, ich habe eine Datei, die mit einer anderen Partition verknüpft ist. Wie würde ich den Pfad zu dieser Originaldatei finden?

54
k-Rocker

Jims Antwort erklärt, wie man auf einen Symlink testet: mit test 's -L Prüfung.

Aber das Testen auf eine "harte Verbindung" ist streng genommen nicht das, was Sie wollen. Hardlinks funktionieren aufgrund der Art und Weise, wie Unix mit Dateien umgeht: Jede Datei wird durch einen einzelnen Inode dargestellt. Dann hat ein einzelner Inode null oder mehr Namen oder Verzeichniseinträge oder technisch harte Links (was Sie eine "Datei" nennen) .

Glücklicherweise kann der Befehl stat, sofern verfügbar, Ihnen mitteilen, wie viele Namen ein Inode hat.

Sie suchen also nach so etwas (hier unter der Annahme der GNU oder Busybox-Implementierung von stat):

if [ "$(stat -c %h -- "$file")" -gt 1 ]; then
    echo "File has more than one name."
fi

Das -c '%h' Bit weist stat an, nur die Anzahl der Hardlinks an den Inode auszugeben, d. h. die Anzahl der Namen, die die Datei hat. -gt 1 prüft dann, ob das mehr als 1 ist.

Beachten Sie, dass Symlinks wie alle anderen Dateien auch mit mehreren Verzeichnissen verknüpft werden können, sodass Sie mehrere Hardlinks zu einem Symlink haben können.

44
derobert

Ein Beispiel:

$ touch f1
$ ln f1 f2
$ ln f1 f3
$ ln -s f1 s1
$ ln -s f2 s2
$ ln -s ./././f3 s3
$ ln -s s3 s4
$ ln s4 s5
$ ls -li
total 0
10802124 -rw-r--r-- 3 stephane stephane 0 Nov 12 19:55 f1
10802124 -rw-r--r-- 3 stephane stephane 0 Nov 12 19:55 f2
10802124 -rw-r--r-- 3 stephane stephane 0 Nov 12 19:55 f3
10802345 lrwxrwxrwx 1 stephane stephane 2 Nov 12 19:56 s1 -> f1
10802346 lrwxrwxrwx 1 stephane stephane 2 Nov 12 19:56 s2 -> f2
10802347 lrwxrwxrwx 1 stephane stephane 8 Nov 12 19:56 s3 -> ./././f3
10802384 lrwxrwxrwx 2 stephane stephane 2 Nov 12 19:56 s4 -> s3
10802384 lrwxrwxrwx 2 stephane stephane 2 Nov 12 19:56 s5 -> s3

Die Verzeichniseinträge f1, f2 Und f3 Sind dieselbe Datei (gleicher Inode: 10802124, Sie werden feststellen, dass die Anzahl von Links 3 beträgt ). Sie sind feste Links zu derselben regulären Datei.

s4 Und s5 Sind ebenfalls dieselbe Datei (10802384). Sie sind vom Typ symlink, nicht regulär. Sie zeigen auf einen Pfad, hier s3. Da s4 Und s5 Einträge desselben Verzeichnisses sind, verweist dieser relative Pfad s3 Für beide auf dieselbe Datei (die mit inod 10802347).

Wenn Sie einen ls -Ll Ausführen, werden Sie nach dem Auflösen von Symlinks aufgefordert, Dateiinformationen abzurufen:

$ ls -lLi
total 0
10802124 -rw-r--r-- 3 stephane stephane 0 Nov 12 19:55 f1
10802124 -rw-r--r-- 3 stephane stephane 0 Nov 12 19:55 f2
10802124 -rw-r--r-- 3 stephane stephane 0 Nov 12 19:55 f3
10802124 -rw-r--r-- 3 stephane stephane 0 Nov 12 19:55 s1
10802124 -rw-r--r-- 3 stephane stephane 0 Nov 12 19:55 s2
10802124 -rw-r--r-- 3 stephane stephane 0 Nov 12 19:55 s3
10802124 -rw-r--r-- 3 stephane stephane 0 Nov 12 19:55 s4
10802124 -rw-r--r-- 3 stephane stephane 0 Nov 12 19:55 s5

Sie finden sie alle auflösen in derselben Datei (10802124).

Sie können mit [ -L file ] Überprüfen, ob eine Datei ein Symlink ist. Ebenso können Sie mit [ -f file ] Testen, ob eine Datei eine reguläre Datei ist. In diesem Fall erfolgt die Überprüfung jedoch nach dem Auflösen von Symlinks.

hardlinks sind keine Dateitypen, sondern nur unterschiedliche Namen für eine Datei (eines beliebigen Typs).

29

Verwendung der -h und -L Operatoren des Befehls test:

-h file 
true if file is a symbolic link

-L file 
true if file is a symbolic link

http://www.mkssoftware.com/docs/man1/test.1.asp

Laut this SO thread haben sie das gleiche Verhalten, aber -L Ist bevorzugt.

19
jimm-cl

Hier gibt es viele ganz richtige Antworten, aber ich glaube nicht, dass irgendjemand die ursprüngliche Fehlwahrnehmung wirklich angegangen ist. Die ursprüngliche Frage lautet im Grunde: "Wenn ich einen symbolischen Link erstelle, ist es einfach, ihn später zu identifizieren. Aber ich kann nicht herausfinden, wie man einen harten Link identifiziert." Und ja, die Antworten beschränken sich im Grunde auf "Sie können nicht" und erklären mehr oder weniger, warum, aber niemand scheint anerkannt zu haben, dass es wirklich IS verwirrend und seltsam ist.

Wenn Sie das alles lesen und herausgefunden haben, was los ist, dann sind Sie gut; du musst mein kleines bisschen nicht lesen. Wenn Sie immer noch verwirrt sind, fahren Sie fort.

Die wirklich sehr kurze Antwort ist, dass ein harter Link überhaupt kein Link ist, nicht so wie ein symbolischer Link. Es ist ein neuer Eintrag in der Verzeichnisstruktur, der auf dieselbe Anzahl von Bytes verweist wie der ursprüngliche Verzeichniseintrag. Sobald Sie ihn erstellt haben, ist er genauso "echt" und legitim wie der erste. Every 'normale' Datei auf Ihrem Laufwerk hat mindestens einen festen Link; Ohne das würden Sie es nicht im Verzeichnis any sehen und könnten nicht darauf verweisen oder es verwenden. Wenn Sie also eine Datei Fred.txt haben und Wilma.txt und Barney.txt fest damit verknüpfen, beziehen sich alle drei Namen (und Verzeichniseinträge) auf dieselbe Datei und sind alle gleichermaßen gültig. Das Betriebssystem kann nicht erkennen, dass einer der Einträge erstellt wurde, als Sie in Ihrem Texteditor auf "Speichern" geklickt haben, und die anderen wurden mit dem Befehl "ln" erstellt.

Das Betriebssystem muss muss jedoch verfolgen, wie viele verschiedene Einträge auf dieselbe Datei verweisen. Wenn Sie Wilma.txt löschen, ist es keine Überraschung, dass Sie keinen Speicherplatz auf Ihrem Laufwerk freigeben. Wenn Sie jedoch Fred.txt (die 'ursprüngliche' Datei) löschen, wird immer noch kein Speicherplatz auf Ihrem Laufwerk frei, da die Daten auf dem Laufwerk, die als Fred.txt bekannt waren, immer noch Barney.txt sind. Nur wenn Sie alle der Verzeichniseinträge löschen, wird das Betriebssystem den Speicherplatz freigeben, den die Daten selbst belegt haben.

Wenn Barney.txt ein symbolischer Link gewesen wäre, hätte das Löschen von Fred.txt würde den Speicherplatz freigegeben, und Barney.txt wäre jetzt ein defekter Link. Wenn Sie eine Datei verschieben oder umbenennen, auf die ein symbolischer Link verweist, wird der Link unterbrochen. Sie können jedoch eine fest verknüpfte Datei nach Belieben verschieben oder umbenennen, ohne die anderen Verzeichniseinträge zu beschädigen, die auf diese Datei/Daten verweisen, da es sich bei allen um Verzeichniseinträge handelt, die auf denselben Datenblock auf dem Laufwerk verweisen (mithilfe von Inode # dieser Daten).

[Es ist zwei Jahre später, und das letzte bisschen verwirrt ich für eine Minute, also denke ich, ich werde es klarstellen. Wenn Sie "mv ./Wilma.txt ../elsewhere/Betty.txt" eingeben, scheint es, als würden Sie die Datei verschieben, aber tatsächlich nicht. Was Sie wirklich tun, ist das Entfernen einer Werbebuchung aus der Verzeichnisliste Ihres aktuellen Verzeichnisses, die besagt, dass "der Name 'Wilma.txt' mit den Daten verknüpft ist, die mithilfe von inode ###### gefunden werden können #, "und Hinzufügen einer neuen Werbebuchung zur Verzeichnisliste des Verzeichnisses ../elsewhere mit der Aufschrift" Der Name 'Betty.txt' ist den Daten zugeordnet, die über den Inode ####### gefunden werden können ". Aus diesem Grund können Sie eine 2-Gigabyte-Datei so schnell wie eine 2-Kilobyte-Datei verschieben, solange Sie sie an einen anderen Speicherort auf demselben Laufwerk verschieben.]

Da das Betriebssystem verfolgen muss, wie viele verschiedene Verzeichniseinträge auf denselben Datenblock verweisen, können Sie können feststellen, ob eine bestimmte Datei fest verknüpft wurde, obwohl Sie dies nicht feststellen können Sicher, ob der Verzeichniseintrag, den Sie sich ansehen, der 'ursprüngliche' ist oder nicht. Eine Möglichkeit ist der Befehl "ls", insbesondere "ls -l" (das ist ein L in Kleinbuchstaben nach dem Bindestrich).

Ein früheres Beispiel ausleihen ....

 -rw-r--r-- 3 stephane stephane 0 Nov 12 19:55 f1

Der erste Buchstabe ist ein Bindestrich, es handelt sich also nicht um ein Verzeichnis oder etwas anderes Exotisches, sondern um eine "normale" normale Datei. Aber wenn es wirklich gewöhnlich wäre, wäre diese Zahl nach dem rwx-ish-Teil "1", wie in "Es gibt einen Verzeichniseintrag, der auf diesen Datenblock verweist". Aber es ist Teil einer Demonstration von harten Links, stattdessen heißt es "3".

Beachten Sie, dass dies möglicherweise zu seltsamem und mysteriösem Verhalten führen kann (wenn Sie Ihren Kopf nicht um harte Links gewickelt haben). Wenn Sie Fred.txt in Ihrem Texteditor öffnen und einige Änderungen vornehmen, werden Sie dieselben Änderungen in Wilma.txt und Barney.txt sehen? Könnte sein. Wahrscheinlich. Wenn Ihr Texteditor die Änderungen speichert, indem Sie die Originaldatei öffnen und die Änderungen darauf schreiben, zeigen alle drei Namen weiterhin auf denselben (neu geänderten) Text. Wenn Ihr Texteditor jedoch eine neue Datei erstellt (Fred-new-temp.txt), Ihre geänderte Version in diese Datei schreibt, dann Fred.txt löscht und Fred-new-temp.txt in Fred.txt umbenennt, werden Wilma und Barney dies tun Zeigen Sie immer noch auf die Originalversion, nicht auf die neue geänderte Version. Wenn Sie Hardlinks nicht verstehen, kann dies Sie leicht verrückt machen. :) [Okay, ich persönlich kenne keine Texteditoren, die die Sache mit der neuen Datei/Umbenennung ausführen würden, aber ich kenne viele andere Programme, die genau das tun, also bleiben Sie warnen.]

Ein letzter Hinweis: Eines der Dinge, auf die 'fsck' (Dateisystemprüfung) prüft, ist, ob sich auf Ihrem Laufwerk Datenblöcke befinden, auf die irgendwie keine Verzeichniseinträge mehr verweisen. Manchmal geht etwas schief und der einzige Verzeichniseintrag, der auf einen Inode verweist, wird gelöscht, aber der Speicherplatz selbst wird nicht als "verfügbar" markiert. Eine der Aufgaben von fsck besteht also darin, den gesamten zugewiesenen Speicherplatz mit allen Verzeichniseinträgen abzugleichen, um sicherzustellen, dass keine nicht referenzierten Dateien vorhanden sind. Wenn es einige findet, erstellt es neue Verzeichniseinträge und legt sie in "lost + found".

4
Snarke

sie können readlink FILE; echo $? verwenden. Dies gibt 1 zurück, wenn es sich um einen Hardlink handelt, und 0, wenn es sich um einen Symlink handelt.

Auf der Manpage: "Beim Aufrufen als Readlink wird nur das Ziel des symbolischen Links gedruckt. Wenn das angegebene Argument kein symbolischer Link ist, gibt readlink nichts aus und wird mit einem Fehler beendet."

3
user2103720