Der Befehl mkdir (kurz für „make directory”) legt leere Verzeichnisse an. Was nach einer Banalität klingt, hat in der Praxis erstaunlich viele Facetten: von verschachtelten Projektstrukturen mit einem einzigen Aufruf über direkt vergebene Permissions bis zur idempotenten Variante für Skripte. Wer mkdir -p versteht, schreibt robustere Shell-Skripte und spart sich endlose if [ -d ... ]-Prüfungen.
Was mkdir macht
mkdir legt ein neues, leeres Verzeichnis im Dateisystem an. Der Befehl gehört zu den GNU-Coreutils und ist auf jedem Linux-System verfügbar. Im Erfolgsfall erscheint kein Output — mkdir arbeitet nach dem Unix-Prinzip „no news is good news”.
mkdir projekteExistiert das Verzeichnis bereits oder fehlt das übergeordnete Verzeichnis, schlägt der Befehl mit einer Fehlermeldung und einem Exit-Code ungleich Null fehl — beides löst die Option -p auf elegante Weise.
Syntax und Optionen
mkdir [OPTION]... VERZEICHNIS...Die wichtigsten Optionen im Überblick:
| Option | Wirkung |
|---|---|
-p, --parents | Legt fehlende Eltern-Verzeichnisse mit an. Kein Fehler, wenn das Ziel bereits existiert. |
-v, --verbose | Gibt für jedes erstellte Verzeichnis eine Meldung aus. |
-m MODE, --mode=MODE | Setzt die Permissions direkt beim Anlegen (z. B. 0700, 755, u+rwx,go=). |
-Z | Setzt SELinux-Kontext auf den Default-Typ. |
--help | Zeigt die Kurzhilfe. |
--version | Zeigt die Version. |
mkdir docs build dist-p ist dein Freund
Ohne -p musst du jede Verzeichnis-Ebene einzeln anlegen — und der Befehl scheitert, sobald eine Zwischenebene fehlt. -p löst beide Probleme: Fehlende Eltern werden automatisch mit angelegt, existierende Verzeichnisse werden ignoriert.
mkdir -p projekt/src/utilsIn Kombination mit der Bash-Brace-Expansion wird -p zum Strukturgenerator. Folgender Befehl legt in einem Schritt ein komplettes Projektgerüst an:
mkdir -pv projekt/{src,test,docs}/{a,b}mkdir: created directory 'projekt'
mkdir: created directory 'projekt/src'
mkdir: created directory 'projekt/src/a'
mkdir: created directory 'projekt/src/b'
mkdir: created directory 'projekt/test'
mkdir: created directory 'projekt/test/a'
mkdir: created directory 'projekt/test/b'
mkdir: created directory 'projekt/docs'
mkdir: created directory 'projekt/docs/a'
mkdir: created directory 'projekt/docs/b'Die Brace-Expansion {src,test,docs} wird von der Shell zu drei Pfaden expandiert, kombiniert mit {a,b} ergeben sich neun Endverzeichnisse — mkdir -p legt alles inklusive der Zwischenebenen an. Mehr dazu im Artikel zur Brace-Expansion.
Permissions beim Anlegen
Standardmäßig erhält ein neues Verzeichnis den Modus 0777 & ~umask. Mit dem typischen umask-Wert 022 ergibt das 0755 — Eigentümer darf alles, Gruppe und andere dürfen lesen und betreten. Welcher umask-Wert in deiner Shell aktiv ist, klärt der Artikel zur Umgebung, das Berechtigungsmodell selbst beschreibt der Artikel zu Berechtigungen.
Mit -m setzt du den Modus direkt — die umask wird dabei ignoriert:
mkdir -m 700 geheim
ls -ld geheimdrwx------ 2 user user 4096 May 5 14:22 geheim-m akzeptiert sowohl oktale Notation (700, 0755) als auch symbolische (u=rwx,g=,o= oder u+rwx,go-rwx). Praktisch für Konfig- und Schlüssel-Verzeichnisse wie ~/.ssh, die strikt 0700 erfordern.
Stille Fehler und Idempotenz
Ohne -p ist mkdir strikt: Existiert das Verzeichnis schon, gibt es einen Fehler und einen Exit-Code ungleich Null. In Skripten ist das oft unerwünscht — du willst, dass das Verzeichnis hinterher existiert, egal ob es vorher schon da war.
mkdir cache
mkdir cache
echo $?mkdir: cannot create directory 'cache': File exists
1Mit -p ist der Befehl idempotent: Mehrfache Aufrufe haben dasselbe Ergebnis wie ein einziger, kein Fehler bei vorhandenem Verzeichnis. Genau das macht -p zur Standard-Wahl in Shell-Skripten:
mkdir -p cache
mkdir -p cache
echo $?0Praxis-Beispiele
Typische Muster aus dem Alltag:
mkdir -p src/{utils,components,api,hooks}Brace-Expansion erzeugt vier Pfade auf einmal — src/utils, src/components, src/api, src/hooks. Mit -p legt mkdir auch das src selbst an, falls es noch nicht existiert. Eine Shell-Zeile statt vier mkdir-Aufrufen.
LOG_DIR="/var/log/myapp"
mkdir -p "$LOG_DIR"
echo "$(date) Start" >> "$LOG_DIR/app.log"Das Skript darf beliebig oft laufen, ohne dass mkdir -p daran scheitert, dass $LOG_DIR schon existiert. Die doppelten Anführungszeichen um ${LOG_DIR} sind Pflicht, sobald der Pfad Leerzeichen enthalten könnte.
mkdir -p ~/.config/myappStandard-Pattern beim Erststart einer Anwendung, die XDG-konform ihre Konfiguration unter ~/.config/ ablegt. -p legt sowohl .config als auch myapp an, falls eines davon fehlt — kein Crash, falls beide schon da sind.
mkdir -p backup/$(date +%Y/%m/%d)Die Command-Substitution $(date +%Y/%m/%d) liefert Pfade wie 2026/05/04. Zusammen mit -p entsteht eine sortierbare Verzeichnisbaum-Hierarchie für tägliche Backups, die sich später bequem mit find -mtime aufräumen lässt.
mkdir -m 700 -p ~/.ssh~/.ssh muss zwingend 0700 haben, sonst verweigert OpenSSH die Nutzung von Privatschlüsseln. -m 700 setzt den Modus direkt beim Anlegen, unabhängig vom aktiven umask — sicherer als ein nachträgliches chmod, weil zwischen mkdir und chmod keine Lücke offen bleibt.
Besonderheiten
-p macht idempotent — perfekt für Skripte
Ein Skript darf mehrfach laufen, ohne dass mkdir -p daran scheitert. Damit ersparst du dir die klassische if [ ! -d "$DIR" ]; then mkdir "$DIR"; fi-Konstruktion. Ein einfaches mkdir -p "$DIR" ist kürzer, robuster und drückt die Absicht klarer aus: „Ich will, dass dieses Verzeichnis hinterher existiert.”
Race-Conditions bei parallelen mkdir-Aufrufen
Wenn zwei Prozesse gleichzeitig mkdir verzeichnis aufrufen, gewinnt einer und der andere bekommt einen Fehler. POSIX garantiert nur, dass das Eltern-Verzeichnis existiert und das Anlegen atomar ist — nicht, dass parallele mkdir-Aufrufe konfliktfrei laufen. Mit -p bekommt der Verlierer keinen Fehler, aber wer das Verzeichnis als Lock verwenden will, sollte mkdir ohne -p nutzen — genau das ist ein etabliertes Lock-Idiom in Shell-Skripten.
install -d als Alternative mit mehr Kontrolle
Der Befehl install -d -m 750 -o www-data -g www-data /var/cache/myapp legt ein Verzeichnis an und setzt in einem Schritt Modus, Eigentümer und Gruppe. Das geht mit mkdir allein nicht — dort bräuchtest du anschließend chmod, chown und chgrp. Praktisch in Setup-Skripten und Build-Pipelines.
Brace-Expansion ist ein Bash-Feature, kein POSIX
mkdir -p projekt/{src,test}/{a,b} funktioniert in Bash und Zsh, aber nicht in einer reinen POSIX-Shell wie dash (dem /bin/sh auf Debian/Ubuntu). In portablen Skripten mit #!/bin/sh musst du die Verzeichnisse einzeln auflisten oder über eine Schleife generieren. Bei #!/bin/bash als Shebang ist Brace-Expansion garantiert.
-m setzt den Modus exakt — umask wird ignoriert
Während ein normales mkdir verzeichnis den Modus aus 0777 & ~umask ableitet, setzt mkdir -m 755 verzeichnis den Modus exakt auf 755, unabhängig vom umask-Wert. Das ist gerade für sicherheitskritische Verzeichnisse wichtig — ~/.ssh mit mkdir -m 700 bekommt garantiert die richtigen Rechte, auch wenn der Benutzer einen ungewöhnlichen umask gesetzt hat.
Bei -p erben Eltern den Default-Modus, nicht den -m-Wert
Hier eine Falle, die viele übersehen: mkdir -m 700 -p a/b/c setzt c auf 0700, aber die zwischengelegten a und b erhalten den Default-Modus aus der umask, nicht 0700. Wer eine ganze Pfadkette mit strengen Rechten anlegen will, muss die Eltern manuell mit chmod nachbessern oder Schritt für Schritt mit eigenen mkdir -m-Aufrufen arbeiten.
Weiterführende Ressourcen
Externe Quellen
- mkdir(1) — Linux man-page — Vollständige Optionsliste und Verhalten
- GNU Coreutils: mkdir invocation — Detaillierte Dokumentation der GNU-Variante
- mkdir(2) — Systemcall — Der zugrundeliegende Kernel-Aufruf
- Arch Wiki: File permissions and attributes — Hintergrund zu Modi, umask und Sonderrechten
- POSIX-Spezifikation: mkdir — Was portabel funktioniert
Verwandte Artikel
- rm und rmdir — Verzeichnisse entfernen — Das Gegenstück zu mkdir
- touch — leere Dateien anlegen — Das Pendant für Dateien
- cd — Verzeichnis wechseln — Navigation im neu angelegten Verzeichnis
- Brace-Expansion — Strukturen in einem Schritt generieren
- Berechtigungen — Modus, Eigentümer und das Unix-Sicherheitsmodell