/usr ist auf einem typischen Linux-System das größte und wichtigste Verzeichnis — hier liegen alle Programme, Bibliotheken, Header-Files, Icons, Fonts, Manpages und Dokumentation, die der Paketmanager installiert. Die Abkürzung stand historisch für „User" (frühe Unix-Systeme legten dort Heimat-Verzeichnisse ab), heute steht sie für „Unix System Resources". Modern wichtig: /usr soll read-only mountbar sein — die Grundlage für atomare Updates, Snapshots und Container-Images.

Was ist /usr?

/usr enthält den Userspace eines Linux-Systems — alles, was zur Distribution gehört, vom Compiler über die Shell bis zum Desktop-Environment. Auf einer Standard-Installation füllt /usr typischerweise 80–95 % des Root-Filesystems: ein Server-Image hat selten mehr als 1–2 GB außerhalb von /usr, ein Desktop-System mit GNOME oder KDE leicht 8–15 GB allein in /usr.

Der FHS-Standard (3.0, Kapitel 4) schreibt zwei Kerneigenschaften fest:

  1. /usr enthält shareable, read-only Daten — also Software und Ressourcen, die von mehreren Maschinen gemeinsam genutzt werden könnten und sich zur Laufzeit nicht ändern.
  2. Innerhalb von /usr liegen Programme, Bibliotheken und Dokumentation architektur-spezifisch oder architektur-unabhängig sortiert.

Historischer Kontext: in frühen Unix-Systemen lagen User-Home-Verzeichnisse direkt unter /usr/<username>/ — daher der Name. Mit zunehmender Trennung der Systembereiche wanderten die Heimat-Verzeichnisse nach /home, und /usr wurde zum Speicher für die Distribution-Software.

Die Struktur unter /usr

/usr ist intern streng strukturiert — fast jeder Unterordner hat eine klar definierte Aufgabe:

PfadInhaltBeispiele
/usr/binDistributions-Programme für alle Nutzervim, python3, git, firefox, gcc
/usr/sbinAdmin-Programme und Daemonssshd, nginx, postfix, cron
/usr/libArchitektur-abhängige Bibliotheken (Shared Objects) und interne Helferlibc.so.6, python3-Module, *.so.*
/usr/lib6464-bit-Bibliotheken (auf einigen Distributionen)RHEL/Fedora-Konvention
/usr/lib/x86_64-linux-gnuMulti-Arch-Bibliotheken (Debian/Ubuntu)Architektur-Subpfad
/usr/libexecProgramme, die nicht direkt vom User aufgerufen werdenHelper-Binaries für Daemons
/usr/shareArchitektur-unabhängige RessourcenIcons, Fonts, Doku, Manpages, Übersetzungen
/usr/includeC/C++-Header-Dateienstdio.h, pthread.h (für Compiler)
/usr/srcKernel- und andere Source-Code-BäumeDistributionspaket-Quellen
/usr/localManuell installierte Software — vom Paketmanager unangetastet/usr/local/bin/myscript
/usr/games(historisch) Spiele und ihre Datenheute meist leer

Die Trennung zwischen /usr/bin und /usr/lib ist wichtig: /usr/bin enthält Programme, die direkt aus der Shell aufgerufen werden, /usr/lib enthält Bibliotheken, die von Programmen geladen werden, sowie interne Helper, die nicht im PATH stehen sollen.

Bash Wieviel Platz beansprucht welcher /usr-Unterbereich?
sudo du -sh /usr/* 2>/dev/null | sort -hr
# 6.2G  /usr/lib
# 3.1G  /usr/share
# 1.2G  /usr/bin
# 240M  /usr/include
# 180M  /usr/src
# 86M   /usr/sbin
# 28M   /usr/local
# ...

/usr/local — der eigene Userspace

/usr/local hat einen Sonderstatus: es ist explizit für lokal installierte oder selbst-kompilierte Software reserviert. Der Paketmanager fasst es nicht an, deshalb können eigene Installationen nie mit Paket-Updates kollidieren — und Distributions-Updates überschreiben nichts, was du selbst kompiliert hast.

Die interne Struktur spiegelt /usr als Mini-System:

PfadZweck
/usr/local/binEigene Binaries — steht im PATH vor /usr/bin
/usr/local/sbinEigene Admin-Tools
/usr/local/libEigene Bibliotheken
/usr/local/includeEigene Header-Dateien
/usr/local/shareEigene Doku, Icons, Daten
/usr/local/etcKonfiguration (alternativ zu /etc)
/usr/local/manEigene Manpages

Der Klassiker-Workflow: ./configure --prefix=/usr/local && make && sudo make install. Damit landen alle Bestandteile sortiert in den passenden /usr/local/*-Unterordnern.

Bash Eigene Binaries in /usr/local/bin
# Eigenes Skript bereitstellen
sudo install -m 755 mein-tool.sh /usr/local/bin/mein-tool

# PATH-Reihenfolge prüfen
echo "$PATH"
# /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

# type zeigt, welche Version effektiv genutzt wird
type -a python3
# python3 is /usr/local/bin/python3   ← lokale Version
# python3 is /usr/bin/python3         ← Distributions-Version

Der wichtige Punkt: /usr/local/bin steht in der Standard-PATH-Reihenfolge vor /usr/bin. Eine selbst kompilierte Version eines Tools übersteuert automatisch die Distributions-Version, ohne dass du etwas konfigurieren musst.

Read-Only-Ambitionen und atomare Updates

Eine zentrale Eigenschaft, die der FHS für /usr festschreibt: das Verzeichnis darf read-only mountbar sein. Programme dürfen also zur Laufzeit nichts schreiben, was unter /usr liegt — schreibbarer State gehört nach /var, /home oder /tmp.

Diese Eigenschaft ist die Grundlage für eine ganze Klasse moderner Distributions-Architekturen:

SystemFunktionsweise
Fedora Silverblue / Kinoite/usr ist ein per ostree verwalteter, signierter Image-Layer — atomare Updates per Boot
NixOS/usr ist (fast) leer; alle Software lebt in /nix/store, das immutable ist
OpenSUSE MicroOSBtrfs-Snapshots von /usr; bei Update wird neuer Snapshot atomar aktiv
Ubuntu CoreSnap-basiertes System mit immutable /usr
ContainerOCI-Images sind effektiv read-only /usr-Snapshots

Vorteile dieser Modelle:

  • Atomare Updates. Entweder das gesamte Update wird wirksam, oder gar keins — keine halb-aktualisierten Zustände nach Strom-Aus.
  • Rollback per Boot. Ein voriger /usr-Snapshot ist beim Bootloader auswählbar, falls ein Update Probleme macht.
  • Reproduzierbare Systeme. Mehrere Maschinen mit demselben /usr-Image sind bit-identisch.

In der klassischen Welt (Debian, Arch, openSUSE Tumbleweed in der Standard-Installation) ist /usr read-write, aber das Prinzip „nichts schreibt zur Laufzeit hier rein" gilt trotzdem — Anwendungen, die Logfiles in /usr ablegen oder dort Caches anlegen, gelten als FHS-Verstoß.

Usr-Merge: warum / und /usr heute zusammenfallen

Auf modernen Distributionen sind /bin, /sbin, /lib etc. Symlinks auf die entsprechenden Unterverzeichnisse von /usr — diese Vereinheitlichung heißt Usr-Merge. Initiiert von Fedora 17 (2012), heute Standard auf praktisch allen wichtigen Distributionen (Debian 12+, Ubuntu 19.04+, RHEL 9+, Arch, openSUSE).

Inhaltlich liegt nach dem Usr-Merge alles unter /usr:

Bash Usr-Merge sichtbar machen
ls -la / | grep -E '^l'
# lrwxrwxrwx ... bin   -> usr/bin
# lrwxrwxrwx ... lib   -> usr/lib
# lrwxrwxrwx ... lib64 -> usr/lib64
# lrwxrwxrwx ... sbin  -> usr/sbin

# /bin/ls und /usr/bin/ls sind dieselbe Datei
stat /bin/ls /usr/bin/ls | grep Inode
# Inode: 12345
# Inode: 12345

Konsequenzen für den Alltag:

  • Skripte mit #!/bin/bash und #!/usr/bin/bash funktionieren beide.
  • Bei der Suche nach Programmen ist es egal, ob du find /bin oder find /usr/bin schreibst — das Ergebnis ist identisch.
  • Beim Backup oder Snapshot musst du nur /usr und einige spezifische Pfade (/etc, /var, /home, /root) sichern — /bin, /sbin, /lib sind über die Symlinks bereits abgedeckt.
  • Beim Schreiben von Dateien: lege niemals Inhalte direkt nur in /bin oder /lib ab und erwarte sie nicht zwingend in /usr/bin — die Symlinks lösen das transparent auf, aber für saubere Skripte bezieh dich immer auf /usr/bin/....

Mehr zum Usr-Merge findest du im Artikel zu /bin.

Praxis: /usr inspizieren

Bash Was steckt in /usr?
# Gesamt-Größe
sudo du -sh /usr

# Größte Pakete in /usr/lib (oft Browser, Office, Compiler)
sudo du -ah /usr/lib | sort -hr | head -10

# Anzahl Programme in /usr/bin
ls /usr/bin | wc -l
# ca. 1500–4000 auf einem voll installierten Desktop

# Welches Paket bringt welche Datei? (Ubuntu/Debian)
dpkg -S /usr/bin/python3
# python3-minimal: /usr/bin/python3

# Manpages für ein Programm finden
ls /usr/share/man/man1/ls*
# /usr/share/man/man1/ls.1.gz
Bash Bibliotheks-Abhängigkeiten eines Programms
# Welche shared libraries lädt ein Programm?
ldd /usr/bin/git | head
# libc.so.6 => /usr/lib/x86_64-linux-gnu/libc.so.6
# ...

# Inverse Suche: wer nutzt diese Bibliothek?
sudo apt-rdepends --reverse libc6 2>/dev/null | head
Bash Manuelle Installation aus Source nach /usr/local
# Klassischer GNU-Workflow
cd /tmp
wget https://example.com/cooltool-1.0.tar.gz
tar xf cooltool-1.0.tar.gz
cd cooltool-1.0

./configure --prefix=/usr/local
make -j$(nproc)
sudo make install

# Hinterher in /usr/local sichtbar
ls /usr/local/bin/cooltool
# /usr/local/bin/cooltool

# Beim späteren Entfernen: meist sudo make uninstall im selben
# Source-Tree (deshalb Source-Trees aufheben oder Tools wie
# checkinstall / paco / stow nutzen).

Interessantes

Niemals direkt in /usr schreiben außer per Paketmanager

Manuelle Änderungen unter /usr (außerhalb von /usr/local) werden beim nächsten Paket-Update überschrieben. Für eigene Tools, Skripte oder kompilierte Software ist /usr/local der einzig richtige Pfad. Wer dort sauber arbeitet, hat auch nach Distributions-Upgrades keine Konflikte.

/usr/share/doc enthält fast immer wertvolle Hinweise

Viele Pakete legen unter /usr/share/doc/<paket>/ README-, CHANGELOG- und Beispiel-Konfigurationen ab — oft tausend Mal informativer als die Manpage. Bei merkwürdigem Verhalten lohnt der erste Blick dorthin: ls /usr/share/doc/<paket>/.

Stow als sauberer /usr/local-Manager

Wer viel selbst kompiliert, sollte sich GNU Stow ansehen: jedes Tool wird in /usr/local/stow/<name>/ installiert und symlinkt in /usr/local/bin, /usr/local/lib etc. Deinstallation = Stow rückgängig machen, kein „verteilter" Zustand mehr. Saubere Alternative zu make install ohne Tracking.

Multi-Arch-Bibliotheken: /usr/lib/x86_64-linux-gnu

Auf Debian und Ubuntu liegen Bibliotheken nicht direkt in /usr/lib, sondern in einer architektur-spezifischen Sub-Hierarchie wie /usr/lib/x86_64-linux-gnu/. Damit lassen sich 32- und 64-bit-Bibliotheken parallel halten — wichtig für i386-Compat oder ARM-Cross-Compiling. Auf Fedora/RHEL läuft das anders über /usr/lib64.

Read-only /usr testen — auch ohne Silverblue

Auch auf einer normalen Distribution kannst du /usr testweise read-only mounten: sudo mount -o remount,ro /usr. Solange keine Anwendung versucht, dort zu schreiben, läuft das System normal weiter. Das ist ein guter Sanity-Check vor der Migration zu einem image-basierten System.

/usr/games existiert, ist aber meist leer

Historisch landeten Spiele in /usr/games und ihre Daten in /usr/share/games — heute installieren die meisten Spielepakete einfach in /usr/bin und /usr/share. Auf modernen Systemen ist das Verzeichnis oft leer oder existiert gar nicht mehr. Dennoch im FHS-Standard noch vorgesehen.

Weiterführende Ressourcen

Externe Quellen

/ Weiter

Zurück zu Verzeichnisstruktur

Zur Übersicht