Unix kennt verschiedene Dateitypen - normale Dateien, Verzeichnisse, Links und Geräte-Dateien. Jeder Typ hat spezifische Eigenschaften und Verwendungszwecke. Links ermöglichen mehrere Namen für die gleiche Datei oder Verweise auf Dateien an anderen Orten. Geräte-Dateien in /dev bilden Hardware als Dateien ab - Festplatten, USB-Sticks und Terminals werden über Standard-Datei-Operationen angesprochen.
Das Inode-Konzept trennt Dateinamen von Datei-Inhalten. Ein Inode speichert die Datei-Metadaten und Speicherorte, der Dateiname ist nur ein Verweis darauf. Diese Trennung ermöglicht Hard Links - mehrere Namen zeigen auf den gleichen Inode, damit auf die gleichen Daten.
Das Inode-Konzept
Was ist ein Inode
Ein Inode (Index Node) ist eine Datenstruktur, die eine Datei beschreibt. Jede Datei hat genau einen Inode, identifiziert durch eine eindeutige Nummer. Der Inode enthält:
- Dateigröße
- Berechtigungen (rwx)
- Eigentümer und Gruppe
- Zeitstempel (Erstellung, Änderung, letzter Zugriff)
- Anzahl der Hard Links
- Zeiger auf die Datenblöcke auf der Festplatte
Der Inode enthält nicht den Dateinamen. Der Dateiname existiert im übergeordneten Verzeichnis, das den Namen mit der Inode-Nummer verknüpft. Ein Verzeichnis ist technisch eine Liste von Dateinamen und zugehörigen Inode-Nummern.
$ ls -i datei.txt
12345678 datei.txt
Die Option -i zeigt die Inode-Nummer - 12345678 in diesem Beispiel. Diese Nummer ist eindeutig innerhalb eines Dateisystems. Zwei Dateien auf der gleichen Partition können nicht die gleiche Inode-Nummer haben.
$ stat datei.txt
File: datei.txt
Size: 2048 Blocks: 8 IO Block: 4096 regular file
Device: 801h/2049d Inode: 12345678 Links: 1
Access: (0644/-rw-r--r--) Uid: ( 1000/ michael) Gid: ( 1000/ michael)
Das stat-Kommando zeigt alle Inode-Informationen. Die Inode-Nummer ist 12345678, die Datei hat einen Link (den Dateinamen), die Berechtigungen sind 0644, Eigentümer ist michael. Die Datenblöcke auf der Festplatte werden über den Inode referenziert - nicht über den Dateinamen.
Verzeichnisse als Inode-Listen
Ein Verzeichnis ist eine spezielle Datei, die Name-zu-Inode-Zuordnungen enthält. Bei ls /home liest das System die Verzeichnis-Datei /home, findet die Inode-Nummern aller Einträge, liest die Inodes für Details (Größe, Berechtigungen) und zeigt die Information an.
$ ls -id /home/michael
1048577 /home/michael
Das Verzeichnis selbst hat auch einen Inode (hier 1048577). Verzeichnisse enthalten mindestens zwei Einträge: . (aktuelles Verzeichnis, zeigt auf eigenen Inode) und .. (Eltern-Verzeichnis, zeigt auf Inode des übergeordneten Verzeichnisses).
Hard Links verstehen
Mehrere Namen für eine Datei
Ein Hard Link ist ein zusätzlicher Verzeichnis-Eintrag für einen existierenden Inode. Beide Namen zeigen auf die gleichen Daten - es gibt keine “Original”-Datei und “Link”, sondern zwei gleichwertige Namen für den gleichen Inhalt.
$ echo "Testdaten" > original.txt
$ ln original.txt kopie.txt
$ ls -li original.txt kopie.txt
12345678 -rw-r--r-- 2 michael michael 10 Okt 6 18:30 kopie.txt
12345678 -rw-r--r-- 2 michael michael 10 Okt 6 18:30 original.txt
Beide Dateien haben die gleiche Inode-Nummer (12345678). Die 2 nach den Berechtigungen zeigt die Link-Anzahl - zwei Namen verweisen auf diesen Inode. Änderungen an kopie.txt erscheinen in original.txt und umgekehrt - es sind nicht zwei Kopien, sondern zwei Namen für die gleiche Datei.
$ echo "Neue Zeile" >> kopie.txt
$ cat original.txt
Testdaten
Neue Zeile
Die Änderung über kopie.txt ist sofort in original.txt sichtbar. Der Inode speichert die Daten, beide Namen greifen darauf zu.
Löschen und Link-Counter
$ rm original.txt
$ ls -li kopie.txt
12345678 -rw-r--r-- 1 michael michael 21 Okt 6 18:32 kopie.txt
Nach rm original.txt existiert kopie.txt noch - der Link-Counter ist von 2 auf 1 gefallen. Der Inode bleibt, die Daten bleiben, nur der Name original.txt ist aus dem Verzeichnis entfernt. Erst wenn der Link-Counter auf 0 fällt, gibt das Dateisystem den Inode und die Datenblöcke frei.
$ rm kopie.txt
$ ls -li kopie.txt
ls: cannot access 'kopie.txt': No such file or directory
Jetzt ist der Link-Counter 0 - der Inode wird freigegeben, die Daten sind gelöscht. Solange mindestens ein Hard Link existiert, bleiben die Daten erhalten. Das macht Hard Links nützlich für Backups - selbst bei versehentlichem Löschen eines Namens bleiben die Daten über den anderen Link erreichbar.
Einschränkungen von Hard Links
Hard Links funktionieren nur innerhalb eines Dateisystems. Ein Link zwischen /home (auf Partition sda1) und /var (auf Partition sda2) ist nicht möglich - jedes Dateisystem hat eigene Inode-Nummern.
$ ln /home/michael/datei.txt /var/backup/datei.txt
ln: failed to create hard link '/var/backup/datei.txt' => '/home/michael/datei.txt': Invalid cross-device link
Die Fehlermeldung “cross-device link” zeigt das Problem - verschiedene Dateisysteme, verschiedene Inode-Tabellen. Für Links über Dateisystem-Grenzen hinweg dienen symbolische Links.
Hard Links auf Verzeichnisse sind verboten (außer . und ..). Sie würden Zyklen im Dateisystem-Baum ermöglichen - Verzeichnis A enthält B, B enthält A. Das würde Tools wie find oder du endlos laufen lassen.
Symbolische Links (Soft Links)
Verweise auf Pfade
Ein symbolischer Link (Symlink, Soft Link) ist eine spezielle Datei, die einen Pfad zu einer anderen Datei enthält. Anders als Hard Links verweisen Symlinks nicht auf Inodes, sondern auf Dateinamen. Sie funktionieren über Dateisystem-Grenzen hinweg und können auf Verzeichnisse zeigen.
$ ln -s /home/michael/dokumente/wichtig.txt shortcut.txt
$ ls -l shortcut.txt
lrwxrwxrwx 1 michael michael 35 Okt 6 18:45 shortcut.txt -> /home/michael/dokumente/wichtig.txt
Das l am Anfang (lrwxrwxrwx) zeigt einen symbolischen Link. Der Pfeil -> zeigt das Ziel. Die Berechtigungen rwxrwxrwx sind Standard für Symlinks - tatsächliche Zugriffsrechte kommen von der Ziel-Datei, nicht vom Link selbst.
$ cat shortcut.txt
Wichtiger Inhalt
Das Lesen von shortcut.txt folgt dem Link, liest /home/michael/dokumente/wichtig.txt. Für den Benutzer ist der Unterschied transparent - die Datei verhält sich wie eine normale Datei.
Absolute vs. relative Symlinks
Symlinks können absolute oder relative Pfade enthalten:
$ ln -s /usr/bin/python3 python
$ ls -l python
lrwxrwxrwx 1 michael michael 16 Okt 6 18:50 python -> /usr/bin/python3
Dieser Link enthält einen absoluten Pfad (/usr/bin/python3). Er funktioniert von jedem Ort aus - ./python führt Python aus, unabhängig vom aktuellen Verzeichnis.
$ cd /home/michael/projekte
$ ln -s ../dokumente/datei.txt link.txt
$ ls -l link.txt
lrwxrwxrwx 1 michael michael 23 Okt 6 18:52 link.txt -> ../dokumente/datei.txt
Dieser Link enthält einen relativen Pfad (../dokumente/datei.txt). Er funktioniert von /home/michael/projekte aus - link.txt zeigt auf /home/michael/dokumente/datei.txt. Wenn das Verzeichnis verschoben wird, bleibt der relative Link funktional, solange die Struktur erhalten bleibt.
Absolute Links zeigen auf feste Pfade - bei Ziel-Verschiebung werden sie ungültig. Relative Links bleiben funktional, wenn Quelle und Ziel zusammen verschoben werden.
Ungültige (Broken) Links
$ ln -s nicht-existent.txt link.txt
$ ls -l link.txt
lrwxrwxrwx 1 michael michael 17 Okt 6 18:55 link.txt -> nicht-existent.txt
$ cat link.txt
cat: link.txt: No such file or directory
Symlinks können auf nicht-existente Ziele zeigen - “broken links”. Das System erstellt den Link ohne Überprüfung des Ziels. Erst beim Zugriff schlägt der Link fehl. Das ls -l zeigt den Link korrekt, cat scheitert mit “No such file or directory”.
$ find . -type l -! -exec test -e {} \; -print
./link.txt
Dieser Befehl findet alle ungültigen links im aktuellen Verzeichnis. -type l filtert Symlinks, -! -exec test -e {} \; prüft ob das Ziel existiert (und invertiert das Ergebnis), -print zeigt defekte Links.
Links auf Verzeichnisse
$ ln -s /var/log logs
$ cd logs
$ pwd
/home/michael/logs
$ pwd -P
/var/log
Der Symlink logs zeigt auf /var/log. Das cd logs funktioniert - Symlinks auf Verzeichnisse sind erlaubt. pwd zeigt den symbolischen Pfad (/home/michael/logs), pwd -P den physischen Pfad (/var/log).
Verzeichnis-Symlinks sind praktisch für häufig verwendete Pfade. /usr/bin/X11 ist oft ein Symlink auf /usr/bin - für eine historische Kompatibilität. Viele Tools erwarten Programme in /usr/bin/X11, der Symlink leitet sie zu /usr/bin.
Hard Links vs. Symbolische Links
Wann welcher Link-Typ
Hard Links verwenden wenn:
- Backup-Schutz benötigt (Daten bleiben bei Löschen eines Links erhalten)
- Gleiche Partition (Hard Links überschreiten keine Dateisystem-Grenzen)
- Normale Dateien (keine Verzeichnisse)
- Transparent identisches Verhalten (kein Unterschied zwischen Original und Link)
Symbolische Links verwenden wenn:
- Über Dateisystem-Grenzen hinweg
- Links auf Verzeichnisse
- Erkennbare Unterscheidung zwischen Link und Ziel gewünscht
- Flexible Pfad-Anpassungen (Ziel kann sich ändern)
Vergleichs-Tabelle
| Eigenschaft | Hard Link | Symbolischer Link |
|---|---|---|
| Funktioniert über Dateisysteme | Nein | Ja |
| Funktioniert auf Verzeichnisse | Nein | Ja |
| Erkennbar als Link | Nein (gleiche Inode) | Ja (eigener Inode, Type ’l') |
| Ziel-Löschung | Daten bleiben erhalten | Link wird ungültig |
| Overhead | Minimal (nur Verzeichnis-Eintrag) | Minimal (kleine Datei mit Pfad) |
| Transparenz | Vollständig transparent | Sichtbar mit ls -l |
Praktische Beispiele
Backup mit Hard Links:
$ cp -al /daten/projekt/ /backup/projekt-2025-10-06/
Die Option -l erstellt Hard Links statt Kopien. Das Backup belegt minimal zusätzlichen Speicherplatz - nur neue oder geänderte Dateien werden wirklich kopiert. Unveränderte Dateien sind Hard Links auf die Originale. Inkrementelle Backup-Tools wie rsync nutzen diese Technik.
Flexible Versionen mit Symlinks:
$ ls -l /usr/bin/python*
lrwxrwxrwx 1 root root 9 Jun 15 2024 /usr/bin/python -> python3.11
lrwxrwxrwx 1 root root 9 Jun 15 2024 /usr/bin/python3 -> python3.11
-rwxr-xr-x 1 root root 5894184 Jun 15 2024 /usr/bin/python3.11
/usr/bin/python ist ein Symlink auf python3, dieser wiederum ein Symlink auf python3.11. Scripts können #!/usr/bin/python nutzen - das System leitet zu der konfigurierten Python-Version um. Bei Python-Updates wird nur der Symlink geändert, nicht alle Scripts.
Gemeinsame Konfiguration:
$ ln -s /opt/config/app.conf ~/.config/app/app.conf
Mehrere Benutzer nutzen die gleiche zentrale Konfiguration über Symlinks. Änderungen an /opt/config/app.conf wirken für alle Benutzer. Individuelle Anpassungen sind über zusätzliche Konfig-Dateien möglich - die Basis bleibt geteilt.
Spezial-Dateien in /dev
Block-Devices und Character-Devices
Das /dev-Verzeichnis enthält Geräte-Dateien (Device Files), die Hardware repräsentieren. Unix behandelt Hardware als Dateien - Lese- und Schreib-Operationen greifen auf Geräte zu statt auf Daten auf der Festplatte.
$ ls -l /dev/sda
brw-rw---- 1 root disk 8, 0 Okt 6 08:15 /dev/sda
Das b am Anfang zeigt ein Block-Device. Block-Devices arbeiten mit festen Blockgrößen (typisch 512 Bytes oder 4 KB) und erlauben wahlfreien Zugriff. Festplatten, SSDs, USB-Sticks sind Block-Devices. Die Zahlen 8, 0 sind Major und Minor Numbers - 8 identifiziert den Geräte-Treiber (SCSI/SATA), 0 die spezifische Instanz (erste Festplatte).
$ ls -l /dev/tty0
crw------- 1 root tty 4, 0 Okt 6 08:15 /dev/tty0
Das c zeigt ein Character-Device. Character-Devices arbeiten zeichenweise und sequenziell. Serielle Schnittstellen, Terminals, Soundkarten sind Character-Devices. /dev/tty0 ist die erste virtuelle Konsole - Schreibvorgänge erscheinen auf dem Bildschirm, Lesevorgänge warten auf Tastatur-Eingaben.
Nützliche Spezial-Devices
/dev/null - Das schwarze Loch:
$ echo "Unwichtige Ausgabe" > /dev/null
$ ls nicht-existent.txt 2>/dev/null
Alles was nach /dev/null geschrieben wird, verschwindet. Das ist nützlich für Ausgaben, die nicht interessieren. Die Umleitung 2>/dev/null schickt Fehler-Meldungen ins Nichts - nur reguläre Ausgabe erscheint auf dem Terminal.
/dev/zero - Unendliche Nullen:
$ dd if=/dev/zero of=datei.bin bs=1M count=100
100+0 records in
100+0 records out
104857600 bytes (105 MB, 100 MiB) copied, 0.123456 s, 849 MB/s
/dev/zero liefert endlos Null-Bytes. Das dd-Kommando liest 100 MB von /dev/zero und schreibt sie in datei.bin - eine Datei gefüllt mit Nullen. Nützlich für Test-Dateien oder zum Überschreiben sensibler Daten.
/dev/random und /dev/urandom - Zufallszahlen:
$ head -c 32 /dev/urandom | base64
5K7j8mP3nQ9xL2vW1R4tY8zN6A0sH5fB
/dev/urandom liefert kryptographisch sichere Zufallsdaten. Dieser Befehl liest 32 Bytes Zufallsdaten, kodiert sie als Base64 - ein Zufallspasswort. /dev/random ist ähnlich, blockiert aber wenn der Entropie-Pool leer ist. /dev/urandom blockiert nie - für die meisten Anwendungen ausreichend.
/dev/loop* - Loop-Devices:
$ sudo losetup -f
/dev/loop0
$ sudo losetup /dev/loop0 disk.img
$ sudo mount /dev/loop0 /mnt
Loop-Devices machen Image-Dateien als Block-Devices verfügbar. Eine ISO-Datei oder Disk-Image kann gemountet werden als wäre es ein physisches Laufwerk. losetup verbindet das Image mit einem Loop-Device, mount macht es im Dateisystem verfügbar.
Device-Nummern verstehen
Die Major Number identifiziert den Geräte-Treiber im Kernel, die Minor Number die spezifische Instanz:
$ ls -l /dev/sd*
brw-rw---- 1 root disk 8, 0 Okt 6 08:15 /dev/sda
brw-rw---- 1 root disk 8, 1 Okt 6 08:15 /dev/sda1
brw-rw---- 1 root disk 8, 2 Okt 6 08:15 /dev/sda2
brw-rw---- 1 root disk 8, 16 Okt 6 08:15 /dev/sdb
Major 8 ist SCSI/SATA. Minor 0 ist die erste Festplatte (sda), Minor 1 die erste Partition (sda1), Minor 2 die zweite Partition (sda2). Minor 16 ist die zweite Festplatte (sdb). Das System kann über diese Nummern direkt mit Treibern kommunizieren.
Named Pipes und Sockets
Named Pipes (FIFOs)
Named Pipes sind spezielle Dateien für Interprozesskommunikation. Sie ermöglichen Datenfluss zwischen Prozessen über das Dateisystem:
$ mkfifo mypipe
$ ls -l mypipe
prw-r--r-- 1 michael michael 0 Okt 6 19:30 mypipe
Das p zeigt eine Named Pipe (FIFO - First In, First Out). Prozess A schreibt in mypipe, Prozess B liest daraus. Die Daten fließen direkt vom Schreiber zum Leser, ohne Zwischenspeicherung auf der Festplatte.
# Terminal 1:
$ echo "Nachricht" > mypipe
# Terminal 2:
$ cat mypipe
Nachricht
Der echo-Befehl blockiert, bis cat die Pipe liest. Dann fließen die Daten durch, beide Befehle beenden sich. Named Pipes sind nützlich für lose gekoppelte Prozesse - sie müssen nicht gleichzeitig laufen, aber mindestens einer muss auf den anderen warten.
Unix-Domain-Sockets
Unix-Domain-Sockets sind Dateien für bidirektionale Kommunikation zwischen Prozessen:
$ ls -l /var/run/docker.sock
srwxrwxrwx 1 root docker 0 Okt 6 08:15 /var/run/docker.sock
Das s zeigt einen Socket. Der Docker-Daemon lauscht auf diesem Socket - Docker-CLI kommuniziert über die Socket-Datei mit dem Daemon. Beide Seiten können senden und empfangen, ähnlich wie Netzwerk-Sockets aber ohne Netzwerk-Overhead.
Dateitypen zusammengefasst
Alle Dateityp-Codes
Das erste Zeichen in ls -l identifiziert den Dateityp:
| Code | Typ | Bedeutung |
|---|---|---|
- |
Regular file | Normale Datei |
d |
Directory | Verzeichnis |
l |
Symbolic link | Symbolischer Link |
b |
Block device | Block-orientiertes Gerät (Festplatte) |
c |
Character device | Zeichen-orientiertes Gerät (Terminal) |
p |
Named pipe | FIFO für Interprozesskommunikation |
s |
Socket | Unix-Domain-Socket |
Dateityp ermitteln
Das file-Kommando identifiziert Dateitypen anhand von Inhalt und Magic Numbers, nicht nur Dateiendungen:
$ file /bin/ls
/bin/ls: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked
$ file dokument.txt
dokument.txt: ASCII text
$ file bild.jpg
bild.jpg: JPEG image data, JFIF standard 1.01
$ file link.txt
link.txt: symbolic link to /home/michael/dokumente/wichtig.txt
Das file-Kommando liest die ersten Bytes der Datei, sucht nach bekannten Mustern (Magic Numbers), identifiziert den Typ. Eine .txt-Datei die tatsächlich ein JPEG ist wird korrekt als JPEG erkannt. Das ist robuster als Vertrauen in Dateiendungen.
Praktische Link-Verwaltung
Alle Links zu einer Datei finden
$ find /home -inum 12345678
/home/michael/original.txt
/home/michael/backup/datei.txt
Das findet alle Pfade mit Inode-Nummer 12345678 - alle Hard Links zu einer Datei. Das -inum sucht nach Inode-Nummer statt Namen.
Symlinks in einem Verzeichnis auflisten
$ find /usr/bin -type l -ls
lrwxrwxrwx 1 root root 9 Jun 15 2024 /usr/bin/python -> python3.11
lrwxrwxrwx 1 root root 9 Jun 15 2024 /usr/bin/python3 -> python3.11
Das -type l filtert symbolische Links. Die -ls Option zeigt Details inklusive Link-Ziel. Das ist nützlich für Übersicht über Symlink-Strukturen in System-Verzeichnissen.
Defekte Links aufräumen
$ find /home/michael -xtype l -delete
Das -xtype l findet Symlinks deren Ziel nicht existiert (broken links). Die -delete Option entfernt sie. Vorsicht: Broken Links können legitim sein - das Ziel kommt später. Erst verstehen warum der Link defekt ist, dann löschen.
Zusammenfassung
Hard Links bieten mehrere Namen für die gleichen Daten über den gleichen Inode. Sie funktionieren nur innerhalb eines Dateisystems und schützen Daten vor versehentlichem Löschen. Symbolische Links sind flexible Verweise auf Pfade, funktionieren über Dateisystem-Grenzen und auf Verzeichnisse.
Spezial-Dateien in /dev machen Hardware als Dateien zugänglich - Block-Devices für Festplatten, Character-Devices für Terminals. Named Pipes und Sockets ermöglichen Interprozesskommunikation über das Dateisystem. Die verschiedenen Dateitypen erweitern Unix-Systeme über normale Dateien hinaus.
Der nächste Artikel behandelt Mount-Points - wie Dateisysteme, USB-Sticks und Netzwerk-Shares in den Verzeichnisbaum eingehängt werden.
Verwendete Software und Versionen
Diese Betrachtung bezieht sich auf:
- Inode-System: Standard seit Unix V7 (1979)
- Betriebssysteme: Alle Linux-Distributionen und BSD-Systeme
- Kontext: Universal für alle Unix-artigen Systeme
- Stand: Oktober 2025
Weiterführende Schritte: