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”.

Bash Einfachster Aufruf
mkdir projekte

Existiert 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

Bash
mkdir [OPTION]... VERZEICHNIS...

Die wichtigsten Optionen im Überblick:

OptionWirkung
-p, --parentsLegt fehlende Eltern-Verzeichnisse mit an. Kein Fehler, wenn das Ziel bereits existiert.
-v, --verboseGibt für jedes erstellte Verzeichnis eine Meldung aus.
-m MODE, --mode=MODESetzt die Permissions direkt beim Anlegen (z. B. 0700, 755, u+rwx,go=).
-ZSetzt SELinux-Kontext auf den Default-Typ.
--helpZeigt die Kurzhilfe.
--versionZeigt die Version.
Bash Mehrere Verzeichnisse auf einmal
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.

Bash Eltern automatisch anlegen
mkdir -p projekt/src/utils

In Kombination mit der Bash-Brace-Expansion wird -p zum Strukturgenerator. Folgender Befehl legt in einem Schritt ein komplettes Projektgerüst an:

Bash Projektstruktur in einem Schritt
mkdir -pv projekt/{src,test,docs}/{a,b}
Output
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:

Bash Privates Verzeichnis (nur Eigentümer)
mkdir -m 700 geheim
ls -ld geheim
Output
drwx------ 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.

Bash Ohne -p — bricht ab
mkdir cache
mkdir cache
echo $?
Output
mkdir: cannot create directory 'cache': File exists
1

Mit -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:

Bash Mit -p — immer Erfolg
mkdir -p cache
mkdir -p cache
echo $?
Output
0

Praxis-Beispiele

Typische Muster aus dem Alltag:

Bash Modul-Skelett für ein JS/TS-Projekt
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.

Bash Robust in einem Skript
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.

Bash Konfig-Verzeichnis im Home anlegen
mkdir -p ~/.config/myapp

Standard-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.

Bash Datums-basierte Backup-Struktur
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.

Bash Privates Schlüssel-Verzeichnis mit korrekten Rechten
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

/ Weiter

Zurück zu Dateisystem

Zur Übersicht