Linux / Befehl dirname: Den Verzeichnisanteil eines Pfads extrahieren

dirname ist ein Befehl, der den letzten Dateinamen oder Verzeichnisnamen aus einer Pfadzeichenkette entfernt und den vorhergehenden Verzeichnisanteil ausgibt. Er ist nützlich in Shell-Skripten, um den übergeordneten Pfad einer Datei zu bestimmen oder einen Pfad zusammen mit basename zu verarbeiten, indem er geteilt wird.

dirname durchläuft das Dateisystem nicht und prüft nicht, ob übergeordnete Verzeichnisse existieren. Es wendet vordefinierte Regeln auf die Eingabezeichenkette an, daher sollten Sie, wenn Sie tatsächliche absolute Pfade oder symbolische Links auflösen müssen, einen Befehl wie realpath verwenden.

Ergänzende Befehle und Anwendungsfälle finden Sie in Liste der häufig verwendeten Befehle in Linux.

Was ist der dirname-Befehl?

Um den Teil eines vollständigen Pfads ohne die letzte Komponente zu erhalten, führen Sie ihn wie folgt aus.

dirname /home/user/report.txt

Die Ausgabe ist wie folgt.

/home/user

Es wird nicht überprüft, ob der letzte Pfadbestandteil der Eingabe tatsächlich eine Datei oder ein Verzeichnis ist. Da es sich um einfache Zeichenkettenverarbeitung handelt, gelten dieselben Regeln auch für Pfade, die nicht existieren.

Grundlegende Syntax und Verwendung

dirname name...

GNU dirname kann mehrere Pfade verarbeiten und jedes Ergebnis auf einer eigenen Zeile ausgeben.

dirname /var/log/nginx/access.log
dirname /home/user/Documents/
dirname relative/path/file.txt

Typische Ergebnisse sind /var/log/nginx, /home/user und relative/path jeweils. Nachgestellte Schrägstriche und aufeinanderfolgende Schrägstriche können während des Bereinigungsprozesses geändert werden, daher sollte es nicht verwendet werden, um die ursprüngliche Zeichenkette unverändert zu bewahren.

Ergebnisse nach Eingabetyp

Eingabe Allgemeine Ausgabe
/home/user/report.txt /home/user
docs/manual.pdf docs
notes.txt .
/usr/ /
/ /

Name ohne Schrägstrich

Wenn kein Schrägstrich in der Eingabe vorhanden ist, wird ein einzelner Punkt, der das aktuelle Verzeichnis darstellt, ausgegeben.

dirname report.txt
.

Dieses Ergebnis bedeutet nicht, dass eine Datei mit dem Namen report.txt tatsächlich im aktuellen Verzeichnis existiert; es stellt den Verzeichnisanteil im Eingabestring dar.

Absoluter Pfad und Stammverzeichnis

Wenn die letzte Komponente eines absoluten Pfads entfernt wird und nur das Stammverzeichnis übrig bleibt, wird / ausgegeben.

dirname /etc
dirname /

Beide Befehle geben im Allgemeinen / aus. Selbst wenn der Elternteil des Stammverzeichnisses als String ausgedrückt wird, ist es immer noch das Stammverzeichnis selbst.

Abschließender Schrägstrich im Pfad

Der unnötige abschließende Schrägstrich wird zuerst entfernt, und dann wird die letzte Komponente verarbeitet.

dirname /srv/www/site/
dirname /srv/www/site///

Beide Eingaben geben im Allgemeinen /srv/www aus. Dies ist nicht geeignet für Aufgaben, die die Anzahl der Schrägstriche oder einen abschließenden Schrägstrich im Original beibehalten müssen.

Verarbeitung mehrerer Pfade

Mehrere Namen gleichzeitig angeben

In der GNU-Implementierung können mehrere Pfade aufgelistet werden.

dirname /srv/www/index.html /var/log/syslog /home/user/file.txt

Der Verzeichnisanteil jeder Eingabe wird in einer separaten Zeile ausgegeben.

/srv/www
/var/log
/home/user

Mit NUL trennen mit -z

In der Automatisierung, bei der Dateinamen Zeilenumbrüche enthalten können, können Sie die Ergebnisse mit einem NUL-Zeichen trennen, indem Sie -z oder --zero verwenden.

dirname -z /srv/www/index.html /var/log/syslog

Da diese Option eine GNU-Erweiterung ist, prüfen Sie die Unterstützung, wenn Sie sie auf anderen Unix-ähnlichen Systemen ausführen müssen.

dirname und basename zusammen verwenden

Sie können den Verzeichnisanteil und den letzten Namen eines Pfads separat extrahieren.

path='/home/user/docs/report.pdf'
directory=$(dirname -- "$path") || exit 1
name=$(basename -- "$path") || exit 1

printf 'Directory: %s\n' "$directory"
printf 'Name: %s\n' "$name"

Die Ausgabe hat die folgende Form.

Directory: /home/user/docs
Name: report.pdf

Diese beiden Befehle sind praktisch, um den ursprünglichen String in zwei sinnvolle Teile zu zerlegen, aber wenn sie wieder kombiniert werden, stellen sie doppelte Schrägstriche oder einen abschließenden Schrägstrich aus dem Original nicht wieder her.

Verwendung in Shell-Skripten

Erstellen des übergeordneten Verzeichnisses einer Ausgabedatei

Sie können das übergeordnete Verzeichnis vorbereiten, bevor Sie eine Datei erstellen.

output='/srv/backups/daily/archive.tar.gz'
output_dir=$(dirname -- "$output") || exit 1
mkdir -p -- "$output_dir"

Wenn der Eingabepfad nicht vertrauenswürdig ist, sollten Sie separat überprüfen, dass er nicht außerhalb des gewünschten Basisverzeichnisses liegt. dirname selbst schränkt den Zugriff nicht ein.

Vergleich mit POSIX Shell Parametererweiterung

Bei einfachem Eingabepfad können Sie den letzten Teil nach einem Schrägstrich mit Shell-Parametererweiterung entfernen.

path='/srv/www/index.html'
directory=${path%/*}
printf '%s\n' "$directory"

Allerdings können Namen ohne Schrägstriche, der Stammverzeichnis-Pfad oder Pfade mit einem abschließenden Schrägstrich andere Ergebnisse als dirname liefern. Wenn die Eingabeformen variieren, testen Sie die Ausnahmen in Ihrer benutzerdefinierten Erweiterung gründlich.

Unterschiede zwischen dirname, realpath und pwd

Befehl Ziel für die Verarbeitung Hauptergebnis
dirname Eingegebener Pfadstring String ohne den letzten Namen
basename Eingegebener Pfadstring Letzter Dateiname oder Verzeichnisname
realpath Angegebener Pfad und Dateisystem Normalisierter Pfad oder Pfad mit aufgelösten symbolischen Links
pwd Aktueller Arbeitsort des Prozesses Absoluter Pfad des aktuellen Arbeitsverzeichnisses

dirname ../logs/app.log gibt ../logs als Zeichenkette aus. Es wird nicht in einen absoluten Pfad relativ zum aktuellen Standort umgewandelt oder symbolische Links aufgelöst.

Zusammenfassung der wichtigsten Optionen

Option Beschreibung
-z, --zero Beendet jedes Ergebnis mit einem NUL-Zeichen anstelle eines Zeilenumbruchs.
--help Zeigt die Verwendung und unterstützten Optionen an.
--version Gibt die installierte GNU Coreutils-Version aus.
-- Nachfolgende Argumente werden als Namen, nicht als Optionen behandelt.

Häufige Probleme

Ergebnis ist ein einzelner Punkt

Weil der Eingabename keinen Schrägstrich enthält. Das Ergebnis von dirname file.txt, das . ist, stellt aus Zeichenkettensicht das aktuelle Verzeichnis dar.

Übergeordnetes Verzeichnis existiert tatsächlich nicht

dirname überprüft das Dateisystem nicht. Um das Ausgabeverzeichnis tatsächlich zu verwenden, müssen Sie seine Existenz und Zugriffsrechte separat überprüfen.

Pfade mit Leerzeichen oder Platzhaltern funktionieren nicht

Schließen Sie Variablen in doppelte Anführungszeichen ein und verwenden Sie -- vor Werten, die mit einem Bindestrich beginnen können.

dirname -- "$path"

FAQ

Findet dirname wirklich das übergeordnete Verzeichnis?

Nein. Es entfernt nur die letzte Komponente aus der Eingabepfadzeichenfolge; es überprüft nicht die tatsächliche Existenz des Pfads oder symbolischer Links.

Warum druckt dirname file.txt einen einzelnen Punkt?

Weil kein Schrägstrich ein Verzeichnis in der Eingabe trennt, wird . gedruckt, was das aktuelle Verzeichnis darstellt.

Können mehrere Pfade gleichzeitig verarbeitet werden?

GNU dirname akzeptiert mehrere Pfade als Argumente und gibt jedes Ergebnis aus. Falls Portabilität mit anderen Unix-Implementierungen erforderlich ist, überprüfen Sie zuerst das unterstützte Format.

Kann ich dirname verwenden, wenn ich einen absoluten Pfad benötige?

dirname wandelt relative Pfade nicht in absolute Pfade um. Wenn Sie einen normalisierten absoluten Pfad benötigen, verwenden Sie die entsprechende Option realpath.

Weitere Angaben zu Syntax, Implementierung und Verfügbarkeit finden Sie unter Offizielle Dokumentation zu GNU Coreutils dirname und POSIX dirname-Spezifikation.