/bin ist das Verzeichnis, in dem die essenziellen Kommandozeilen-Programme liegen, die jedes Linux-System zwingend braucht — ls, cp, mv, cat, grep, ps, kill, sh, bash und viele mehr. Historisch ist /bin derjenige Pfad, der schon vor dem Mounten von /usr verfügbar sein muss, damit das System überhaupt startfähig ist. Auf modernen Distributionen ist /bin heute meist ein Symlink auf /usr/bin (Usr-Merge), die Rolle als minimale Werkzeugkiste bleibt aber dieselbe.
Was steckt in /bin?
Im Kern enthält /bin die Programme, die für eine funktionierende Shell-Sitzung und einfache Systemwartung unverzichtbar sind. Das umfasst Datei- und Verzeichnis-Operationen, Text-Anzeige und -Manipulation, Prozess-Verwaltung und einige System-Werkzeuge.
| Kategorie | Typische Programme |
|---|---|
| Datei- und Verzeichnis-Operationen | ls, cp, mv, rm, mkdir, rmdir, ln, chmod, chown, chgrp, touch, pwd |
| Text- und Datenanzeige | cat, echo, printf, more, less, head, tail, grep, sed, sort, uniq |
| Shells und Skripting | sh, bash, dash, [, test, true, false |
| Prozesse und Signale | ps, kill, killall, nice, wait |
| System-Information | hostname, uname, date, dmesg, df, du, mount, umount |
| Netzwerk-Basis | ping, hostname, oft auch nc (netcat) |
| Notfall-Helfer | dd, sync, cpio, tar, gzip, bzip2 |
Was du dort nicht findest: alles, was nicht für den Boot- oder Single-User-Modus essenziell ist. Texteditoren wie vim, Compiler, Skriptsprachen, Server-Daemons, Desktop-Software — all das gehört nach /usr/bin oder bei manueller Installation nach /usr/local/bin.
Auf einem typischen modernen System (Ubuntu 24.04, Debian 13, Fedora 41) findest du in /bin rund 150 bis 250 Einträge — größtenteils Coreutils plus die vom Linux Standard Base (LSB) geforderten Pflicht-Werkzeuge.
Der FHS-Standard und die Mindestanforderungen
Die Existenz und der Inhalt von /bin sind im Filesystem Hierarchy Standard (FHS) spezifiziert — derselbe Standard, der auch /etc, /usr, /var und Co. definiert. Die aktuelle FHS-Version 3.0 schreibt für /bin zwei Eigenschaften fest:
/binmuss zur Verfügung stehen, damit Single-User-Maintenance möglich ist — also auch dann, wenn/usr(noch) nicht gemountet ist./binenthält Befehle, die alle Benutzer verwenden können müssen, nicht nur Administratoren.
Die FHS legt eine Mindestliste an Befehlen fest, die in /bin vorhanden sein müssen, sofern das jeweilige Programm überhaupt installiert ist:
| FHS-Pflicht-Befehle | Zweck |
|---|---|
cat, chgrp, chmod, chown, cp, date | Grundlegende Datei- und Datums-Operationen |
dd, df, dmesg, echo, false, hostname | Low-Level-Datenverarbeitung, System-Info |
kill, ln, login, ls, mkdir, mknod, more, mount | Prozesse, Verzeichnisse, Mounts |
mv, ps, pwd, rm, rmdir, sed, sh, stty, su | Dateien, Prozess-Anzeige, Shell, User-Switch |
sync, true, umount, uname | Disk-Sync, Truthy/Falsy, Unmount, Kernel-Version |
Distributionen erweitern die FHS-Liste meist um GNU-Coreutils-Standards wie head, tail, sort, uniq, printf oder Bash-spezifische Werkzeuge. Eine FHS-konforme Distribution darf zusätzliche Programme in /bin ablegen, muss aber die Pflicht-Liste enthalten.
# Pflicht-Befehle gegen das tatsächliche /bin abgleichen
for cmd in cat chgrp chmod chown cp date dd df dmesg echo \
false hostname kill ln login ls mkdir mknod more \
mount mv ps pwd rm rmdir sed sh stty su sync true \
umount uname; do
command -v "$cmd" >/dev/null || echo "FEHLT: $cmd"
doneAuf einem voll installierten Desktop-System gibt diese Schleife normalerweise nichts aus — alle Pflicht-Befehle sind vorhanden. Auf einem minimalen Container-Image (alpine, busybox) kann durchaus etwas fehlen, weil dort viele „Befehle” als Symlinks auf busybox realisiert sind.
/bin vs /sbin vs /usr/bin vs /usr/local/bin
Die FHS sieht insgesamt vier Binary-Verzeichnisse vor, die sich nach Zielgruppe und Quelle unterscheiden. Wer einmal versteht, wer wo hingehört, weiß auch, wo er ein bestimmtes Programm suchen muss — und wo eigene Skripte abgelegt werden sollten.
| Pfad | Zielgruppe | Inhalt | Beispiel |
|---|---|---|---|
/bin | Alle Nutzer | Essenzielle Kommandos, im Single-User-Modus verfügbar | ls, cat, cp |
/sbin | Administrator (root) | Systemverwaltung, Netzwerk-Setup, Filesystem-Tools | fdisk, mount, iptables, ip |
/usr/bin | Alle Nutzer | Distributions-Software, Anwendungen, große Tools | vim, python3, git, firefox |
/usr/sbin | Administrator | Daemons, weitere System-Tools | sshd, postfix, nginx |
/usr/local/bin | Alle Nutzer | Manuell installierte Software (nicht vom Paketmanager) | Selbst kompilierte Tools, Helper-Skripte |
/usr/local/sbin | Administrator | Manuell installierte Admin-Tools | Eigene Backup-Skripte |
Die Aufteilung folgt zwei Achsen: Nutzergruppe (alle vs. nur root) und Quelle (essenziell + Distribution vs. lokal/manuell installiert).
In der Praxis steht der PATH auf der meisten Distributionen so, dass /usr/local/bin vor /usr/bin durchsucht wird — eigene Builds übersteuern damit automatisch eine eventuell vorinstallierte Distributions-Version. Für Admin-Skripte, die nicht aus dem Paketmanager kommen, ist /usr/local/sbin der richtige Ort.
type ls
# ls is aliased to `ls --color=auto'
type -a python3
# python3 is /usr/bin/python3
# python3 is /usr/local/bin/python3 ← lokale Version steht vor distros
which mount
# /usr/bin/mount ← nach Usr-Merge effektiv /bin
command -v fdisk
# /usr/sbin/fdisk
ls -la /sbin /usr/sbin | head -20Hinweis: Manche Distributionen (z. B. Arch Linux) haben /sbin ebenfalls per Symlink auf /usr/bin zusammengelegt — der konzeptionelle Unterschied „nur für root” wird dann nur noch durch Datei-Berechtigungen (z. B. fehlende Lese- und Ausführungsrechte für Nicht-Root-Nutzer) und nicht mehr durch den Pfad ausgedrückt.
Usr-Merge: warum heute alles auf /usr/bin zeigt
Auf den meisten aktuellen Distributionen ist /bin heute schlicht ein Symlink auf /usr/bin — und ebenso /sbin → /usr/sbin, /lib → /usr/lib. Diese Vereinheitlichung wird Usr-Merge genannt und wurde zwischen 2012 und 2024 sukzessive umgesetzt:
| Distribution | Usr-Merge ab |
|---|---|
| Fedora | Version 17 (2012) — erster Vorreiter |
| Arch Linux | 2012, vollständig 2013 |
| openSUSE | 13.2 (2014) |
| Solus | seit Beginn (2014) |
| Ubuntu | 19.04 (2019) |
| RHEL / CentOS | 9 (2022) |
| Debian | 12 „Bookworm” (2023) verpflichtend |
| Alpine Linux | weitgehend, seit Anfang |
Der Symlink ist absichtlich auf der Verzeichnis-Ebene gesetzt — er leitet jeden Zugriff um:
ls -la / | grep -E '^l'
# lrwxrwxrwx 1 root root 7 ... bin -> usr/bin
# lrwxrwxrwx 1 root root 7 ... lib -> usr/lib
# lrwxrwxrwx 1 root root 9 ... lib32 -> usr/lib32
# lrwxrwxrwx 1 root root 10 ... lib64 -> usr/lib64
# lrwxrwxrwx 1 root root 8 ... sbin -> usr/sbin
readlink /bin
# usr/bin
# Effektiv die gleiche Datei
stat /bin/ls /usr/bin/ls | grep Inode
# Inode: 12345
# Inode: 12345Inhaltlich ändert der Usr-Merge nichts — beide Pfade zeigen auf dieselben Programme. Der eigentliche Gewinn liegt in der Wartbarkeit auf System-Ebene:
- Atomare Updates und Snapshots. Wenn
/usrein eigener Mount-Punkt ist (etwa als read-only Subvolume bei Btrfs oder als image-basiertes Update bei Fedora Silverblue, NixOS, OpenSUSE MicroOS), ist es deutlich einfacher, das gesamte Userspace-Stage atomar zu tauschen, ohne dass/binoder/libin den Root-Filesystem-Bereich „lecken”. - Cross-Distribution-Kompatibilität. Skripte und Container-Images können sich auf einen einzigen Pfad stützen — der Shebang
#!/usr/bin/env bashfunktioniert überall,#!/bin/bashebenfalls (über den Symlink). - Boot- und Init-Vereinfachung. Im Zeitalter von
initramfsund systemd ist die alte Trennung „erst/, dann/usrmounten” technisch obsolet. Ein vereinheitlichter Userspace passt zur tatsächlichen Boot-Reihenfolge moderner Systeme.
Was nicht funktioniert: der Versuch, auf einem Usr-Merged-System eine Datei nur in /bin und nicht in /usr/bin abzulegen — der Symlink macht das physikalisch unmöglich. Skripte oder Buildsysteme, die das versuchen, müssen angepasst werden.
Boot-Reihenfolge und Single-User-Modus
Der historische Grund für die strikte Trennung zwischen /bin und /usr/bin lag in der Boot-Reihenfolge alter Unix-Systeme:
- Das Root-Filesystem (
/) wurde gemountet — mit/bin,/sbin,/etc,/lib. - Das System startete in den Single-User-Modus (Runlevel 1, „maintenance mode”) und lief nur mit den Programmen aus
/binund/sbin. - Erst danach wurde
/usraus einer eventuell separaten Partition gemountet —/usr/binwurde verfügbar. - Das System ging in den Multi-User-Modus über (Runlevel 3 oder 5).
Diese Reihenfolge erforderte zwingend, dass alle Werkzeuge zur System-Reparatur (also: Filesystem prüfen, Konfiguration korrigieren, Backup einspielen) in /bin und /sbin lagen — Werkzeuge aus /usr/bin standen schlicht nicht zur Verfügung.
In modernen Linux-Systemen mit initramfs und systemd ist diese Trennung weitgehend obsolet:
- Das initramfs (eine kleine, in den Hauptspeicher geladene RAM-Disk mit eigenem Mini-Userspace, oft auf BusyBox-Basis) übernimmt das Mounten aller Filesysteme —
/usrist von Anfang an verfügbar, sobald das eigentliche System startet. - systemd kennt keinen klassischen Runlevel mehr; stattdessen gibt es Targets wie
rescue.targetundemergency.target. Diese laufen mit dem vollen Userspace (inklusive/usr/bin). - Der Single-User-Modus existiert noch als Fallback (
systemctl rescueoder Boot-Parametersystemd.unit=rescue.target), bringt aber den kompletten/usr-Stack mit.
Trotzdem behalten die Pfade ihre Rolle — und in Embedded-Systemen, Routern, BusyBox-basierten Containern und alten oder konservativen Systemen (z. B. einigen BSDs) ist die ursprüngliche Trennung weiter relevant.
Praxis: /bin auf deinem System inspizieren
Ein paar nützliche Kommandos, um zu verstehen, was auf deinem konkreten System los ist:
# Wieviele Programme stecken in /bin?
ls /bin | wc -l
# Größte Binaries (z. B. zur Inspektion vor Cleanup)
du -ah /bin | sort -hr | head -20
# Alle Symlinks in /bin auflisten — viele Programme sind nur
# Aliase, etwa awk → gawk oder vi → vim.basic
find /bin -maxdepth 1 -type l -printf '%f -> %l\n'
# Alphabetische Liste mit Datei-Typ
file /bin/* 2>/dev/null | head -20Die Datei-Größe der Binaries ist auf modernen Systemen größtenteils wenige hundert KB pro Programm — der überwältigende Anteil sind die Coreutils, die statisch verlinkte Versionen mancher Programme sind aber merklich größer.
# Debian/Ubuntu: dpkg-Datenbank fragen
dpkg -S /bin/ls
# coreutils: /bin/ls
# Fedora/RHEL: rpm fragen
rpm -qf /bin/ls
# coreutils-9.5-1.fc41.x86_64
# Arch: pacman fragen
pacman -Qo /bin/ls
# /usr/bin/ls is owned by coreutils 9.5-1Praktisch bei Debugging: kommt ein bestimmtes Werkzeug von der Distribution oder von einem Drittanbieter? Der Paketmanager kennt jede Datei in /bin und sagt dir, zu welchem Paket sie gehört.
# Welche Programme in /bin haben SUID gesetzt?
find /bin -maxdepth 1 -perm -4000 -type f -ls 2>/dev/null
# ... -rwsr-xr-x ... /bin/su
# ... -rwsr-xr-x ... /bin/mount
# ... -rwsr-xr-x ... /bin/umount
# ... -rwsr-xr-x ... /bin/ping ← bei manchen DistributionenSUID („set user ID”) sorgt dafür, dass das Programm mit den Rechten des Datei-Owners (meist root) statt mit denen des aufrufenden Nutzers läuft. Klassisches Beispiel ist su — ohne SUID könnte ein normaler User nicht in den Root-Account wechseln. Im Hardening solltest du diese Liste regelmäßig prüfen, weil jeder SUID-Eintrag eine potenzielle Privilege-Escalation-Quelle ist.
Interessantes
Eigene Skripte gehören NICHT in /bin
Auch wenn man der Versuchung ausgesetzt sein könnte: Selbstgeschriebene Helper-Skripte landen nicht in /bin. Erstens überschreibt das nächste System-Update den Inhalt potenziell, zweitens vermischst du Distribution-Software mit lokaler. Der korrekte Pfad ist /usr/local/bin für alle User oder ~/.local/bin für nur den eigenen User — beide stehen im PATH und werden vor /usr/bin gefunden.
Der Shebang #!/bin/sh ist kein Bash
Auf vielen Distributionen ist /bin/sh ein Symlink auf dash (Debian, Ubuntu) oder bash (Arch, openSUSE) — manchmal sogar auf mksh (Android-Welt). Skripte mit #!/bin/sh müssen sich strikt an POSIX halten, sonst brechen sie auf einem dash-System. Bash-Spezifika wie Arrays oder [[ ... ]] brauchen explizit #!/bin/bash.
busybox liefert eine Mini-/bin in einem Binary
Embedded-Systeme, Recovery-Images und Container wie Alpine Linux nutzen oft BusyBox — ein einziges Binary, das Hunderte Mini-Implementierungen klassischer Unix-Befehle vereint. ls, cp, mv usw. sind dort Symlinks auf /bin/busybox. Der Vorteil: extrem klein (1–2 MB für die komplette Werkzeugkiste), der Preis: viele Optionen fehlen oder verhalten sich anders als die GNU-Versionen.
Statisch vs. dynamisch verlinkte /bin-Programme
Standardmäßig sind die Programme in /bin dynamisch gegen die System-Bibliotheken in /lib und /usr/lib gelinkt. Manche Distributionen liefern aber wichtige Programme zusätzlich als statisch gelinkte Variante (z. B. bash-static, ldconfig.real) — sie funktionieren auch dann noch, wenn das Linker-System gerade kaputt ist. Mit ldd /bin/ls siehst du die Abhängigkeiten eines Programms.
ping ist auf neueren Systemen kein SUID mehr
Lange Zeit war /bin/ping SUID-root, weil das Programm einen RAW-Socket öffnen muss. Auf neueren Linux-Kernels (≥ 4.3) gibt es stattdessen Linux Capabilities: cap_net_raw=p reicht, ein klassisches SUID ist nicht mehr nötig. Distributionen wie Fedora und Ubuntu sind bereits umgestellt — getcap /bin/ping zeigt die effektiven Capabilities.
Der Pfad /bin existiert auch noch ohne Usr-Merge
Sehr alte Embedded-Systeme, statisch konstruierte Container oder einige BSD-Derivate (FreeBSD, OpenBSD) trennen weiterhin strikt zwischen /bin und /usr/bin — kein Symlink, sondern echte Verzeichnisse. Beim Schreiben portabler Skripte sollte man sich auf /usr/bin/env <prog> als Shebang verlassen, nicht auf hartkodierte Pfade.
Weiterführende Ressourcen
Externe Quellen
- Filesystem Hierarchy Standard 3.0 — /bin
- Fedora UsrMove Feature
- Debian /usr-Merge Status
- Arch Linux: The Case for the /usr Merge
- Linux man-pages: hier(7) — Beschreibung der Verzeichnisstruktur