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

51

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 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 finde ich die Zielpartition eines symbolischen Links? Angenommen, ich habe eine Datei, die auf eine andere Partition verweist. Wie würde ich den Pfad zu dieser Originaldatei finden?

k-Rocker
quelle
16
Was meinst du mit festem Link? Alle Dateien sind feste Links.
terdon
1
@terdon ln /foo/bar/ /foo/bar2macht einen Hardlink, während er ln -s /foo/bar /foo/bar2einen Symlink macht, das ist was er meint?
Anzeigename
14
@DisplayName ja, aber alle Dateien sind feste Links zu ihrem Inode. So funktionieren Linux-Dateisysteme. In Ihrem Beispiel sind bar2und barbeide Hardlinks, die nur auf den gleichen Inode verweisen.
terdon
10
@DisplayName ja, sie sind feste Links zu anderen Inodes . Hier besteht kein Widerspruch. Eine Datei ist eine Verknüpfung zu einer Inode. Das ist die Definition einer Datei. In Ihrem Fall haben Sie diese Links an verschiedenen Stellen, aber das ändert nichts an der zugrunde liegenden Datenstruktur. Mein Punkt ist, dass beide barund bar2gleich wichtig sind. Einer ist kein Link zum anderen, beide sind Links, zeigen aber auf den gleichen Inode.
Terdon
3
@Scott nein, ich sage, dass normale Dateien Hardlinks sind und dass Hardlinks, die von erstellt wurden, lnsich nicht von normalen Dateien unterscheiden.
Terdon

Antworten:

42

Jims Antwort erklärt, wie man auf einen Symlink testet: mit testdem -LTest von.

Aber das Testen auf eine "harte Verbindung" ist genau genommen nicht das, was Sie wollen. Harte Links 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 gesehen harte Links (was Sie eine "Datei" nennen).

Zum Glück statkann Ihnen der Befehl, sofern verfügbar, mitteilen, wie viele Namen eine Inode hat.

Also suchst du 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 teilt statmit, nur die Anzahl der Hardlinks an den Inode auszugeben, dh die Anzahl der Namen, die die Datei hat. -gt 1prü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.

derobert
quelle
OK, nur um klar zu sein, kann ich die Anzahl der Hardlinks, die die Datei hat, mit dem Befehl stat ausgeben und wenn es größer als 1 ist, dann hat es eine andere Datei, die irgendwo auf der Partition verlinkt ist.
k-Rocker
@ k-Rocker Ja. Dann hat es irgendwo auf der Partition einen zweiten Namen.
Derobert
1
Unter OS X oder * BSD ist es stat -f %l /path/to/file. Sie könnten auch verwenden, gstat -c %h /path/to/filewenn Sie die GNU-Core-Utils ohne deren Standardnamen installiert haben (mit Homebrew unter OS X).
GDP2
29

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, f2und f3sind dieselbe Datei (derselbe Inode: 10802124, Sie werden feststellen, dass die Anzahl der Links 3 beträgt). Sie sind feste Links zu derselben regulären Datei.

s4und s5sind auch die gleiche Datei (10802384). Sie sind vom Typ symlink und nicht regulär . Sie zeigen hier auf einen Pfad s3. Da s4und s5Einträge desselben Verzeichnisses sind, s3verweist dieser relative Pfad für beide auf dieselbe Datei (die mit inod 10802347).

Wenn Sie eine ls -Llausführen, werden Sie aufgefordert, Dateiinformationen abzurufen, nachdem Sie Symlinks aufgelöst haben:

$ 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 lösen auf die gleiche Datei (10.802.124).

Sie können prüfen, ob es sich bei einer Datei um einen Symlink handelt [ -L file ]. Ebenso können Sie testen, ob es sich bei einer Datei um eine reguläre Datei [ -f file ]handelt. In diesem Fall erfolgt die Überprüfung jedoch nach dem Auflösen von Symlinks.

Hardlinks sind keine Art von Dateien, sondern lediglich unterschiedliche Namen für eine Datei (egal welchen Typs).

Stéphane Chazelas
quelle
19

Verwenden der Operatoren -hund -Ldes testBefehls:

-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 diesem SO-Thread haben sie das gleiche Verhalten, werden aber -Lbevorzugt.

jimm-cl
quelle
ok cool, aber was ist mit harten links? Ich habe das Profil überprüft, aber nichts über harte Links. Wenn -L false zurückgibt, bedeutet dies, dass es sich um eine harte Verknüpfung handelt? oder nur eine normale datei?
k-Rocker
1
Harte Links haben dasselbe gemeinsam inode. Außerdem zeigen Softlinks eine lam Anfang ihrer ls -lAusgabe ... Ich denke, Sie können diese Regeln möglicherweise in einem Skript zusammenfassen und [[ -L file ]]testen, ob die angegebene Datei entweder soft oder hard ist .
jimm-cl
OK, auch, wie würde ich die Zielpartition des symbolischen Links finden?
k-Rocker
3

Hier gibt es viele recht richtige Antworten, aber ich glaube nicht, dass irgendjemand die ursprüngliche Fehlwahrnehmung wirklich in Angriff genommen hat. Die ursprüngliche Frage lautet im Grunde: "Wenn ich einen symbolischen Link erstelle, kann ich ihn später leicht identifizieren. Ich kann jedoch nicht herausfinden, wie ein fester Link zu identifizieren ist." Und ja, die Antworten beschränken sich im Grunde auf "Sie können nicht" und erklären mehr oder weniger, warum, aber niemand scheint zu erkennen, dass es wirklich verwirrend und seltsam ist.

Wenn Sie all dies 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 fester Link überhaupt kein Link ist, nicht so wie ein symbolischer Link. Es handelt sich um einen neuen Eintrag in der Verzeichnisstruktur, der auf die gleiche Anzahl von Bytes verweist wie der ursprüngliche Verzeichniseintrag. Sobald Sie ihn erstellt haben, ist er genauso "echt" und legitim wie der erste. Jede "normale" Datei auf Ihrem Laufwerk verfügt über mindestens einen festen Link. ohne das würdest du es in keinem sehenVerzeichnis, und wäre nicht in der Lage, darauf zu verweisen oder es zu verwenden. Wenn Sie also eine Datei Fred.txt haben und Wilma.txt und Barney.txt fest damit verknüpfen, verweisen alle drei Namen (und Verzeichniseinträge) auf dieselbe Datei, und sie 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 jedoch nachverfolgen, 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 'Original'-Datei) löschen, wird trotzdem kein Speicherplatz auf Ihrem Laufwerk freigegeben, da die Daten auf dem Laufwerk, die als Fred.txt bezeichnet wurden, weiterhin auch Barney.txt sind. Nur wenn Sie alle Verzeichniseinträge löschen, wird der von den Daten selbst belegte Speicherplatz vom Betriebssystem freigegeben.

Wenn Barney.txt eine symbolische Verknüpfung gewesen wäre, hätte das Löschen von Fred.txt die Zuordnung des Speicherplatzes aufgehoben, und Barney.txt wäre jetzt eine fehlerhafte Verknüpfung. Wenn Sie eine Datei verschieben oder umbenennen, auf die eine symbolische Verknüpfung verweist, wird die Verknüpfung unterbrochen. Sie können eine fest verknüpfte Datei jedoch beliebig verschieben oder umbenennen, ohne die anderen Verzeichniseinträge zu unterbrechen, die auf diese Datei / Daten verweisen, da es sich bei allen um Verzeichniseinträge handelt, die auf denselben Datenblock auf dem Laufwerk verweisen Inode # dieser Daten).

[Es ist zwei Jahre später und das letzte bisschen verwirrte mich für eine Minute, also denke ich, dass ich es klären werde. Wenn Sie "mv ./Wilma.txt ../elsewhere/Betty.txt" eingeben, scheint es, als würden Sie die Datei verschieben, aber in Wirklichkeit ist dies nicht der Fall. Was Sie wirklich tun, ist, eine Werbebuchung aus der Verzeichnisliste Ihres aktuellen Verzeichnisses zu entfernen, die besagt, dass "der Name 'Wilma.txt' mit den Daten verknüpft ist, die mit inode ###### gefunden werden können. #, "und Hinzufügen einer neuen Werbebuchung zur Verzeichnisliste von directory ../elsewhere, die besagt, dass" der Name 'Betty.txt' mit den Daten verknüpft ist, die über inode ####### gefunden werden können ". Aus diesem Grund können Sie eine 2-Gigabyte-Datei genauso schnell wie eine 2-Kilobyte-Datei verschieben, solange Sie sie an einen anderen Speicherort auf demselben Laufwerk verschieben.]

Da das Betriebssystem nachverfolgen muss, wie viele verschiedene Verzeichniseinträge auf den gleichen Datenblock verweisen, können Sie feststellen , ob eine bestimmte Datei fest verknüpft ist, auch wenn Sie nicht mit Sicherheit feststellen können, ob der Verzeichniseintrag auf Sie verweist guck mal ist das 'original' 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“ Datei. Aber wenn es wirklich normal wäre, wäre diese Zahl nach dem rwx-ish-Teil "1", wie in "es gibt einen Verzeichniseintrag, der auf diesen Datenblock zeigt". Aber es ist Teil einer Demonstration von Hardlinks, also steht stattdessen "3".

Beachten Sie, dass dies möglicherweise zu seltsamem und mysteriösem Verhalten führen kann (wenn Sie sich nicht um harte Links gekümmert haben). Wenn Sie Fred.txt in Ihrem Texteditor öffnen und einige Änderungen vornehmen, werden Sie dieselben Änderungen in Wilma.txt und Barney.txt sehen? Vielleicht. Wahrscheinlich. Wenn Ihr Texteditor die Änderungen speichert, indem er die Originaldatei öffnet und die Änderungen darauf schreibt, werden alle drei Namen weiterhin auf denselben (neu geänderten) Text zeigen. Wenn Ihr Texteditor jedoch eine neue Datei erstellt (Fred-new-temp.txt), schreibt er Ihre geänderte Version in diese Datei, löscht Fred.txt und benennt Fred-new-temp.txt in Fred.txt um. Wilma und Barney werden es tun verweist weiterhin auf die ursprüngliche Version, nicht auf die neu geänderte Version. Wenn du harte Links nicht verstehst, kann das dich leicht verrückt machen. :) [Okay, ich persönlich kenne keineTexteditoren , die das Neue-Datei / Umbenennen-Ding machen würden, aber ich kenne viele andere Programme, die genau das tun, also sei wachsam.]

Ein letzter Hinweis: Eines der Dinge, auf die 'fsck' (Dateisystemprüfung) prüft, ist, ob sich Datenblöcke auf Ihrem Laufwerk befinden, auf die von keinem Verzeichniseintrag mehr verwiesen wird. 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 Aufgabe von fsck ist es daher, den gesamten zugewiesenen Speicherplatz mit allen Verzeichniseinträgen abzugleichen, um sicherzustellen, dass keine nicht referenzierten Dateien vorhanden sind. Wenn es welche findet, erstellt es neue Verzeichniseinträge und legt sie in "Fundbüro" ab.

Snarke
quelle
Ich frage mich nur, was sind diese "anderen Programme, die genau das tun"?
Phk
@phk Weiß nicht, worüber er konkret nachdenkt, aber das ist ein gängiger Ansatz, um Aktionen durchzuführen, die lange dauern können und Sie in einen unsicheren Zustand versetzen, wenn sie fehlschlagen. Wenn Sie beispielsweise versuchen, Daten von einem Remoteserver herunterzuladen, und Sie wissen, dass das Zeitlimit des Servers möglicherweise überschritten wird, besteht ein Ansatz darin, den gesamten Inhalt in eine temporäre Datei herunterzuladen. Auf diese Weise haben Sie immer noch die Originaldatei, wenn beim Herunterladen etwas schief geht.
Cwallenpoole
Das einzige Programm, das ich mit Sicherheit kenne, ist FreeHand, denn wenn / wenn es beim Speichern abstürzt, bleibt eine temporäre Datei zurück und keine beschädigte Originaldatei. Aber ich habe auch andere Programme gesehen, die das gemacht haben. Ich kann Ihnen derzeit keine konkreten Beispiele nennen.
Snarke
2

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

Aus der Manpage: "Beim Aufruf als Readlink wird nur das Ziel des symbolischen Links gedruckt. Wenn das angegebene Argument kein symbolischer Link ist, druckt Readlink nichts und wird mit einem Fehler beendet."

user2103720
quelle