rekursives mkdir

305

Gibt es einen Linux-Befehl, den ich übersehen habe, der es ermöglicht, etwas in der Art von: (Pseudo) zu tun?

$ mkdir -R foo/bar/zoo/andsoforth

Oder gibt es keine Alternative, als die Verzeichnisse einzeln zu erstellen?

Braiam
quelle
1
lustig, ich habe diese Seite angesehen, aber "Eltern" völlig übersehen, weil ich sie als Kinder betrachtete (von links nach rechts).
18
Protip: In einigen Shells kann man das sogar machen mkdir -p foo/{bar,baz}/zoo/andsoforth. Sehr hilfreich!
Aaron Copley
1
Persönlich habe ich "parent" in der Manpage ebenfalls übersehen, weil ich der Meinung bin, dass das Flag "-r" für "recursive" sein sollte - oder zumindest sollte es einen Alias ​​für einen solchen geben, mkdirder nur 6 hat dokumentierte Flaggen insgesamt. Meiner Meinung nach sollte der Befehl Verzeichnisse standardmäßig rekursiv erstellen, und wenn Sie dies nicht möchten, müssen Sie dies explizit angeben.
Bogenschütze

Antworten:

511
$ mkdir -p foo/bar/zoo/andsoforth
EEAA
quelle
92
Zu Ihrer Information die -p steht für „Eltern“
carl Crott
14
Sie hätten stattdessen -r machen können, wie bei jedem anderen Befehl, bei dem es unmöglich ist, sich bestimmte Parameter für jeden Linux-Befehl zu merken
Vedmant
2
mkdir -p
Ist
9
@ РоманКоптев mkdir -pwird in POSIX angegeben , was der vollständigen Portierbarkeit am nächsten kommt. Was erwarten Sie besser in einem Shell-Skript?
Wildcard
5
@StephanBijzitter Ja, das ist unix.se, nicht unixandwindows.se. :)
EEAA
16

Die Verwendungmkdir -p ist für die meisten modernen Betriebssysteme ein einfacher Weg:

mkdir -p foo/bar/zoo/andsoforth

In mkdir -pvielen Handbüchern wird dies jedoch nicht empfohlen. Lesen Sie die Dokumentation zu GNU makeund autoconfzu Problemen bei der Verwendung von mkdir -p:

Die plattformübergreifenden Installations- und Konfigurationssysteme haben ihre eigenen sicheren Alternativen fürmkdir -p .

CMake zur Verwendung in der Shell-Befehlszeile:

 cmake -E make_directory foo/bar/zoo/andsoforth

Autoconf zur Verwendung in Skripten mit Vorverarbeitung:

AS_MKDIR_P(foo/bar/zoo/andsoforth)

oder:

AC_PROG_MKDIR_P(foo/bar/zoo/andsoforth)

Aber diese Lösungen erfordern cmakeoder autoconf( M4) Tools installiert werden (und mögliche Vorverarbeitung)

Sie können auch install-shSkript mit -dOption verwenden:

install-sh -d foo/bar/zoo/andsoforth

Dieses Skript wird von autoconfund automakeproject verwendet. Ich denke, es muss die sicherste Lösung sein.

Zu der Zeit habe ich nach einer plattformübergreifenden Lösung für Standard /bin/shohne Abhängigkeiten gesucht , aber keine gefunden. Aus diesem Grund habe ich das nächste Skript geschrieben, das möglicherweise nicht ideal ist, aber meiner Meinung nach die meisten plattformübergreifenden Anforderungen erfüllt :

#! /bin/sh

cdirname() # cross platform alternative for 'dirname'
{
  # $1 - path
  test $# -eq 1 || { echo "Procedure 'cdirname' must have only one parameter. Scripting error."; exit 1; }
  echo "$1" | sed -n -e '1p' | sed  -e 's#//*#/#g' -e 's#\(.\)/$#\1#' -e 's#^[^/]*$#.#' -e 's#\(.\)/[^/]*$#\1#' -
}

mkd() # cross platform alternative for 'mkdir -p'
{
  # $1 - directory to create
  test $# -eq 1 || { echo "Function 'mkd' can create only one directory (with it's parent directories)."; exit 1; }
  test -d "$1"  && return 0
  test -d "$(cdirname "$1")" || { mkd "$(cdirname "$1")" || return 1; }
  test -d "$1" || { mkdir "$1" || return 1; }
  return 0
}

Dieses Skript kann für alte Systeme verwendet werden, bei denen die Option -pfür mkdirfehlt.

sed-basierte plattformübergreifende Version von dirnamewurde zum Code hinzugefügt. Es funktioniert auf ähnliche Weise wie dirname(richtig mit Pfad /, nur Pfade mit Basisnamen /, Pfade mit und ohne nachfolgendem \ns). Diese Funktion kann nicht korrekt ausgeführt werden, wenn der Pfad Zeilenumbrüche oder ungültige Zeichen für das aktuelle Gebietsschema enthält. Es ersetzt auch jede Kombination von /( //, ///) mit single/

Geänderte Zeile mkdir "$1" || return 1in test -d "$1" || { mkdir "$1" || return 1; }weil wird mkdirmit Fehler beendet, wenn Pfad vorhanden ist und diese Prüfung für Pfade mit Konstruktionen wie erforderlich ist aaa\.(Wenn aaanicht vorhanden, wird die vorherige Version erstellt aaaund dann versucht, sie erneut zu erstellen).

Diese Version von mkd generiert keinen Fehler, wenn der Pfad bereits vorhanden ist (es besteht jedoch weiterhin die Möglichkeit, einen solchen Fehler bei der parallelen Ausführung zu generieren), und es können nicht mehrere Verzeichnisse in der Befehlszeile abgerufen werden.

Роман Коптев
quelle
4
"mkdir -p" wird durch posix definiert. Welche Unix- oder Unix-ähnlichen Varianten unterstützen das nicht? (Und es sollte keine eingebaute Shell sein, obwohl es wohl keinen Grund dafür gibt.) pubs.opengroup.org/onlinepubs/9699919799/utilities/mkdir.html
Tim B
5
Einige der Informationen auf dieser Seite sind erst 15 Jahre alt. Einige sind älter.
Thomas Dickey
7
Systeme, die nicht unterstützt mkdir -pwürden, wären zu alt (und wir sprechen von mindestens ein paar Jahrzehnten), um ein printfHilfsprogramm oder einen Support --zu haben, um das Ende der Optionen zu markieren.
Stéphane Chazelas
2
Sie cdirnamewürden die falsche Antwort für foo/bar//oder Verzeichnisnamen mit Zeilenumbrüchen oder ungültigen Zeichen im aktuellen Gebietsschema eingeben.
Stéphane Chazelas
2
printfist auf POSIX-Systemen sicher. POSIX-Systemunterstützung mkdir -p. mkdir -pwird seit Jahrzehnten von POSIX spezifiziert. --Beginn der Verbreitung auf AT & T-Systemen, beginnend mit SysIII, Mitte der 80er Jahre. printferschien zuerst als kshBuiltin, glaube ich, und wurde später von POSIX spezifiziert als mkdir -p. Einige POSIX-Shells (wie Pdksh- oder Yash-basierte) haben noch keine printfeingebauten.
Stéphane Chazelas
0

Option -pin Befehl mkdirmacht p Arent Verzeichnisse nach Bedarf (kein Fehler , wenn vorhanden):

mkdir -p foo/bar/zoo/andsoforth

Eine andere Möglichkeit ist zum Beispiel &&(Fehler, wenn der angegebene Ordner existiert):

mkdir foo && mkdir foo/bar && mkdir foo/bar/zoo && mkdir foo/bar/zoo/andsoforth

Der Verkettungsoperator &&wird zum Verketten von Befehlen verwendet, sodass der nächste Befehl genau dann ausgeführt wird, wenn der vorherige Befehl fehlerfrei beendet wurde.

Natürlich ist der erste Weg besser.

simhumileco
quelle
-3
mkdir foo foo/bar foo/bar/zoo/ foo/bar/zoo/andsofort.

Das sollte es tun.

Kanchan Kumar
quelle