# 1.104.7

# Erzeugen und Ändern von harten und symbolischen Links

Beschreibung: Prüfungskandidaten sollten in der Lage sein, harte und symbolische Links auf eine Datei zu verwalten. Dieses Lernziel beinhaltet das Erzeugen und Bestimmen von Links, das Kopieren von Dateien über Links und das Verwenden von verknüpften Dateien zur Unterstützung von Tätigkeiten der Systemadministration.

Die wichtigsten Dateien, Bezeichnungen und Anwendungen:

- ln

Links sind eine Spezialität von Unix-Dateisystemen, die gerne und häufig verwendet werden. Der Umgang mit ihnen ist eine wichtige und manchmal etwas verkopfte Angelegenheit, die ein Systemverwalter sicher beherrschen muß.

Unix und Linux unterscheiden zwischen Hardlinks (direkte Links) und Symlinks (symbolische Links). Die Eigenschaften dieser beiden Typen von Links sowie die Techniken, um sie anzulegen bzw. mit ihnen umzugehen sind Inhalt dieses Kapitels.

### Hardlinks

In einem Unix-Dateisystem ist ein Dateiname nur ein Verzeichniseintrag, der in einem Verzeichnis gespeichert ist. Neben diesem Namen ist immer auch ein Verweis auf die Inode gespeichert, die dann die eigentlichen Eigenschaften (Eigentümer, Gruppenmitgliedschaft, Zugriffsrechte, usw.) der Datei und ihre physikalischen Speicheradressen auf der Platte enthält. Dieses Prinzip wurde auf den Seiten über Inodes und über das EXT2 Dateisystem bereits umfassend dargestellt.

Ein Hardlink ist nichts anderes, als ein neuer Verzeichniseintrag auf eine schon bestehende Inode. Also genau genommen ein zweiter Dateiname für eine Datei. Weil die Zugriffsrechte, Eigentümer usw. ja in der Inode stehen, haben alle Hardlinks einer Datei die selben solchen Attribute.

Wenn ein oder mehrere Hardlinks auf eine Datei zeigen, so ist nicht mehr zu unterscheiden, welcher davon das Original und welche die Links sind. Es handelt sich ja einfach nur um Namenseinträge, die auf die selbe Inode zeigen. Das heißt auch, daß Hardlinks immer noch gültig sind, wenn die Datei, auf die sie zeigen gelöscht wurde. Es wurde ja eben nicht die Datei gelöscht, sondern nur einer ihrer Namen. Solange noch weitere Namen existieren, wird die Datei nicht physikalisch gelöscht.

Die Ausgabe des `ls -l` Kommandos zeigt für jede Datei gleich nach dem Zugriffsmodus die Anzahl der Hardlinks (also der Namenseinträge), die diese Datei besitzt.

    -rw-r--r--   1 root     root         4326 Apr  8 15:02 datei1.txt
    -rw-r--r--   5 root     root         1578 Apr  8 15:02 datei2.txt

Auch hier wird nicht zwischen Original und Link unterschieden (geht ja eben auch gar nicht) so daß eine Datei mit nur einem Namen hier eine 1 anzeigt. Die zweite Datei des obigen Beispiels hat also 5 Namen, das könnte bedeuten, daß die Datei erstellt wurde und anschließend vier Hardlinks auf sie erstellt wurden. Insgesamt existieren also 5 Namenseinträge für diese Datei.

Da die Hardlinks sozusagen innerhalb der Mechanismen eines Dateisystems arbeiten indem sie eigentlich nur Verweise auf schon bestehende Inodes sind, arbeiten diese Links nur innerhalb der Grenzen eines Dateisystems also einer Partition. Es ist also nicht möglich, Hardlinks auf einer zweiten Partition zu erstellen, die auf eine Datei zeigen, die auf der ersten Partition liegt!

Eine weitere Einschränkung von Hardlinks ist, daß es nicht möglich ist, Hardlinks auf Verzeichnisse zu legen. Es existiert zwar die Option -d (oder -F oder --directory) des Befehls ln, die die Fähigkeit erlauben soll, auf allen Linux-Dateisystemen ist dieses Feature aber verboten.

### Symbolische Links

Die genannten Einschränkungen der Hardlinks (keine Links auf Verzeichnisse/ keine Links über die Dateisystemgrenze hinaus) können mit sogenannten symbolischen Links umgangen werden. Symbolische Links arbeiten nicht auf der Dateisystemebene, sondern sind einfach Dateien, die nichts anderes enthalten, als den Pfad zu der Datei (oder dem Verzeichnis), auf die sie zeigen. Damit sie als Links zu erkennen sind, haben sie einen eigenen Dateityp (`l`), der es dem Betriebssystem klar macht, daß es sich hier um einen Link und nicht um eine reguläre Datei handelt.

Das `ls -l` Kommando zeigt einen symbolischen Link also als solchen an:

    -rw-r--r--   1 root     root       276295 Apr 21 19:46 Datei1
    lrwxrwxrwx   1 root     root            6 Apr 21 19:46 Datei2 -> Datei1

Sowohl an der Angabe des Dateityps (`l`, als auch am Dateinamen, dem ein Pfeilsymbol und das Ziel des Links folgt, ist ersichtlich, daß es sich hier um einen symbolischen Link handelt. Genauso ist ersichtlich, worauf der Link zeigt. Beim Hardlink konnten wir Original und Link nicht unterscheiden, beim symbolischen Link sind sie eindeutig unterscheidbar.

Weil symbolische Links nicht auf der Ebene der Dateisysteme selbst arbeiten reagieren sie aber auch in anderen Beziehungen völlig anders, als die Hardlinks:

- Wenn die Datei (oder das Verzeichnis), auf die ein symbolischer Link zeigt nicht mehr existiert (z.B. gelöscht wurde), dann zeigt der symbolische Link "ins Leere", der Link existiert zwar weiter, er funktioniert aber nicht mehr.
- Wird ein symbolischer Link mit einer relativen Pfadangabe erstellt und anschließend in ein anderes Verzeichnis kopiert, dann wird er womöglich nicht mehr weiter funktionieren, weil vom neuen Verzeichnis aus dieser Pfad nicht existiert.

Andererseits sind die symbolischen Links nicht eingeschränkt, was die Grenzen eines Dateisystems angeht oder die Verwendung für Verzeichnisse.

### Das Programm ln

Um Links anzulegen, existiert das Programm ln. Die Aufrufform ist einfach,

      ln [-s] Datei [Link]

Wird das Programm `ln` ohne den Parameter `-s` oder `--symbolic` aufgerufen, so wird ein Hardlink erstellt, mit einem dieser beiden Optionsschaltern wird ein symbolischer Link erstellt.

Wenn ein Hardlink erstellt wird, so muß die Datei, auf die der Link verweist existieren, wenn ein symbolischer Link erstellt wird, so gilt das nicht.

Wird beim Aufruf von ln der Linkname weggelassen, so wird ein Link mit gleichem Namen wie die Datei im aktuellen Verzeichnis erzeugt. Das setzt aber natürlich voraus, daß die Datei nicht im aktuellen Verzeichnis liegt.

Werden mehr als zwei Dateinamen angegeben (Datei und Link), so muß der letzte Parameter ein Verzeichnisname sein. In diesem Verzeichnis werden dann Links auf all die Dateien angelegt, die vor diesem letzten Parameter angegeben wurden.

Normalerweise überschreibt das Programm ln keine Dateien, wenn ein Link angelegt werden soll, dessen Namen schon existiert. ln bietet aber eine Fülle von Optionen, die diese Eigenschaft ändert, inclusive der Frage der automatischen Umbenennung von überschriebenen Dateien.

### Identifikation von Hardlinks

Wie oben schon erwähnt, gibt es keine Möglichkeit, zwischen Hardlink und Original zu unterscheiden, weil es ja kein Original gibt, sondern nur mehrere Namen, die alle auf die gleiche Inode verweisen. Wenn wir nun herausfinden wollen, welche Dateinamen alle die selbe Inode verwenden, gibt es da durchaus eine Möglichkeit:

Zunächst einmal müssen wir herausbekommen, welche Inode von unserer Datei überhaupt belegt wird. Das `ls`-Kommando bietet uns mit der Option `-i` die Möglichkeit, das zu erfahren. Ein `ls -i` gibt uns zu den Dateinamen die verwendeten Inode-Nummern mit aus.

Dann können wir mit dem Programm `find` nach allen Dateien suchen, die diese Inode-Nummer benutzen. Allerdings sollten wir das ausschließlich innerhalb der Partition tun, auf der die Datei liegt, die wir untersuchen. Denn zufälligerweise kann ja eine ganz andere Datei auf einem ganz anderen Dateisystem (also auf einer anderen Partition) die selbe Inode-Nummer benutzen.

Spielen wir es einmal durch: Wir befinden uns im Verzeichnis `/usr/local/data` und das `ls -l` Kommando zeigt uns eine Datei mit Namen `BEISPIEL.DAT` folgendermaßen an:

    -rw-r--r--   5 root     root         1895 Apr  8 15:02 BEISPIEL.DAT

Aus der Angabe direkt nach dem Zugriffsmodus entnehmen wir, daß es insgesamt fünf Dateinamen gibt, die auf ein und dieselbe Inode verweisen. Also neben dieser Datei noch vier weitere. Zunächst müssen wir wissen, welche Inode diese Datei überhaupt benutzt. Dazu geben wir den Befehl

      ls -i BEISPIEL.DAT

ein und bekommen die folgende Ausgabe:

      92550 BEISPIEL.DAT

Die benutzte Inode ist also die Inode Nummer 92550. Jetzt müssen wir herausbekommen, auf welcher Partition wir uns eigentlich befinden und wo sie im Verzeichnisbaum eingehängt ist. Wir geben den Befehl `df` ohne weitere Parameter ein. Die Ausgabe lautet:

    /dev/hda2              2071328   1047620    918484  53% /
    /dev/hda5              3099108   1737192   1204484  59% /usr
    /dev/hda6              2071296    767708   1198364  39% /opt
    /dev/hda7              2071296    215212   1750860  11% /home

Nachdem wir uns im Verzeichnis `/usr/local/data` befinden, können wir also aus dieser Ausgabe schließen, daß wir uns auf der Partition `/dev/hda5` befinden und daß diese Partition ins Verzeichnis `/usr` gemountet ist. Jetzt rufen wir den `find`-Befehl auf und weisen ihn an, ab dem Verzeichnis `/usr` alle Dateien zu suchen, die die Inode 92550 benutzen. Zusätzlich weisen wir ihn noch darauf hin, daß er nur dieses eine Dateisystem durchsuchen soll. Dazu kennt find die Option `-xdev`. Wir geben folgenden Befehl ein:

      find /usr -xdev -inum 92550 -print

Der Befehl `find` sucht ab dem Verzeichnis `/usr` aber nur innerhalb der Partition (`-xdev`) alle Dateien, die die Inode 92550 (`-inum 92550`) besitzen. Die gefundenen Dateien werden ausgegeben (`-print`). Die Anweisung `-print` hätten wir unter Linux auch weglassen dürfen, es ist hier die voreingestellte Aktion. Das Ergebnis sieht dann etwa wie folgt aus:

      /usr/lib/Beispiel/Datei.txt
      /usr/local/data/BEISPIEL.DAT
      /usr/local/lib/Beispiel/Noch_eine
      /usr/openwin/Hier_auch
      /usr/src/abc

Hätten wir dem `find`-Befehl statt der Aktion `-print` die Aktion `-ls` mitgegeben, die alle gefundenen Dateien im selben Format wie `ls -dils` ausgibt, dann hätten wir die folgende Ausgabe bekommen:

     92550    5 -rw-r--r--   1 root     root         1895 Apr  8 15:02 /usr/lib/Beispiel/Datei.txt
     92550    5 -rw-r--r--   1 root     root         1895 Apr  8 15:02 /usr/local/data/BEISPIEL.DAT
     92550    5 -rw-r--r--   1 root     root         1895 Apr  8 15:02 /usr/local/lib/Beispiel/Noch_eine
     92550    5 -rw-r--r--   1 root     root         1895 Apr  8 15:02 /usr/openwin/Hier_auch
     92550    5 -rw-r--r--   1 root     root         1895 Apr  8 15:02 /usr/src/abc

Eine weitere Möglichkeit der Identifikation von Hardlinks wäre es, ein `ls -ilR` Kommando (langes Listing mit Inode-Nummern, rekursiv) auszuführen und dessen Ausgabe an `grep` weiterzuleiten. Grep würde dann nach der entsprechenden Inode-Nummer am Zeilenanfang suchen. Also für unser opiges Beispiel etwas in der Art:

      ls -ilR /usr | grep "^ *92550"

Das hat allerdings den Nachteil, daß wir nicht festlegen können, daß nur die Dateien innerhalb einer Partition gesucht werden. Zum anderen ist diese Art der Suche wesentlich langsamer als die mit dem `find`-Befehl.

### Kopieren symbolischer Links

Wenn ein symbolischer Link mit dem Befehl `cp` kopiert wird, ohne daß dazu bestimmte Optionen gegeben werden, so wird nicht etwa der Link kopiert, sondern die Datei, auf die der Link zeigt. Das Ergebnis (die Zieldatei) ist jetzt also kein Link, sondern eine reguläre Datei. Man spricht in diesem Zusammenhang von der Dereferenzierung eines Links.

Dereferenzierung bedeutet, daß der Link zurückverfolgt wird, und durch das ausgetaucht wird, auf das er zeigt.

Um das zu vermeiden, muß dem `cp`-Befehl eine spezielle Option mitgegeben werden, die diese Dereferenzierung unterbindet. Wenn wir also einen symbolischen Link als solchen kopieren wollen, das heißt wenn das Ziel der Kopieraktion wiederum ein Link sein soll, so müssen wir dem Kopierbefehl die Option `-d` oder `--no-dereference` mitgeben.

Aber bitte Vorsicht walten lassen! Wenn ein symbolischer Link als Link kopiert wird, dann wird der Link genauso kopiert, wie er war. Falls er keine absolute, sondern eine relative Pfadangabe zu dem Objekt beinhaltet, auf das er verweist, so wird die Kopie genau die Selbe Pfadangabe haben. Es ist nicht gewährleistet, daß diese Angabe von der neuen Lokalität aus immer noch stimmt.

Am Rande bemerkt: Der `cp`-Befehl ist selbst auch in der Lage, Links zu erzeugen statt Dateien zu kopieren. Mit der Option `-l` erzeugt er Hardlinks statt Kopien und mit `-s` symbolische Links.

### Verwenden von Links zur Systemadministration

In der Systemverwaltung werden Links auf vielfältige Weise eingesetzt. Dabei kommen sowohl Hard- als auch symbolische Links zur Anwendung. Ein paar Beispiele:

Vermeidung versehentlichen Löschens mit Hardlinks
  Wichtige Systemdateien können an andere Orte gelinkt werden, wo sie sozusagen eine Versicherung gegen versehentliches Löschen bieten. Nehmen wir an, Sie erstellen ein Verzeichnis `/etc2` und verlinken alle wichtigen Dateien in `/etc` mit Hardlinks in dieses Verzeichnis. Sollte jetzt eine Datei in `/etc` gelöscht werden, so steht sie uns immer noch in der aktuellsten Version in `/etc2` zur Verfügung.
Zentrale Verwaltung wichtiger Startdateien in den Userverzeichnissen
  Jeder User hat in seinem Home-Verzeichnis verschiedene Startdateien oder andere Konfigurationsdateien. Soll sichergestellt werden, daß alle User immer die gleichen Einstellungen besitzen, so könnten all diese Dateien Hardlinks auf einen Prototyp sein. Wenn der Systemverwalter jetzt für alle User eine Veränderung vornehmen will, so muß er nur eine dieser Dateien (etwa den Prototyp) verändern und alle Dateien der User sind mitverändert.
Symbolische Links auf Verzeichnisse
  Wenn bestimmte Teile des Verzeichnisbaums ReadOnly gemountet sein sollen, aber andererseits Unterverzeichnisse dieser Teile beschreibbar sein müssen, so können diese Unterverzeichnisse symbolische Links auf andere Unterverzeichnisse sein, die nicht auf ReadOnly-gemounteten Partitionen liegen. Das `/usr` Verzeichnis wird z.B. gerne ReadOnly gemountet, enthält aber Verzeichnisse wie `tmp` oder `spool`, die beschreibbar sein müssen. Diese Verzeichnisse sind oft symbolische Links auf entsprechende Verzeichnisse unter `/var`. Dort sind diese Verzeichnisse tatsächlich beschreibbar.