Wie kann ich nur mkdir, wenn noch kein Verzeichnis vorhanden ist?

1987

Ich schreibe ein Shell-Skript, das unter der KornShell (ksh) unter AIX ausgeführt werden soll. Ich möchte den mkdirBefehl verwenden, um ein Verzeichnis zu erstellen. Möglicherweise ist das Verzeichnis jedoch bereits vorhanden. In diesem Fall möchte ich nichts tun. Daher möchte ich entweder testen, ob das Verzeichnis nicht vorhanden ist, oder den Fehler "Datei vorhanden" unterdrücken, der mkdirbeim Versuch, ein vorhandenes Verzeichnis zu erstellen, ausgelöst wird.

Irgendwelche Gedanken darüber, wie man das am besten macht?

Spike Williams
quelle

Antworten:

3294

Versuchen Sie mkdir -p:

mkdir -p foo

Beachten Sie, dass dadurch auch Zwischenverzeichnisse erstellt werden, die nicht vorhanden sind. zum Beispiel,

mkdir -p foo/bar/baz

erstellt Verzeichnisse foo, foo/barund foo/bar/bazwenn sie nicht vorhanden sind.

Einige Implementierungen wie GNU mkdirenthalten mkdir --parentseinen besser lesbaren Alias, der jedoch nicht in der POSIX / Single Unix-Spezifikation angegeben ist und auf vielen gängigen Plattformen wie macOS, verschiedenen BSDs und verschiedenen kommerziellen Unixen nicht verfügbar ist. Daher sollte dies vermieden werden.

Wenn Sie einen Fehler wünschen, wenn übergeordnete Verzeichnisse nicht vorhanden sind, und das Verzeichnis erstellen möchten, wenn es nicht vorhanden ist, können Sie zunächst Folgendes feststellen test:

[ -d foo ] || mkdir foo
Brian Campbell
quelle
11
Das verkürzte Beispiel, das Sie verwenden, ist genau das, was Sie nicht tun sollten. Es kehrt die Logik um, um Codierungsplatz zu sparen, sollte aber verwendet werden! und && und machen für diejenigen, die es lesen, mehr Sinn.
Mike Q
16
@AndreasLarsen Diese Frage bezieht sich mkdirauf Unix-ähnliche Systeme, nicht auf Windows. -pist für die Einhaltung der POSIX / Single Unix-Spezifikation erforderlich, sodass alles unterstützt wird, was diese Spezifikationen erfüllen soll -p. Windows ist völlig anders, es sei denn, Sie verwenden eine POSIX-Emulationsebene wie Cygwin oder MSYS.
Brian Campbell
22
Ich habe heute etwas Interessantes entdeckt, mit dem mkdir -pman Klammern verwenden kann! {}um einen "komplexen" Verzeichnisbaum in einem Befehl zu erstellen. Siehe hier: technosophos.com/2010/04/15/...
herve
12
@MikeQ Ich würde es vorziehen , ||statt , &&weil dann die ganze Linie hat den richtigen Exit - Status. Wichtig, wenn Ihre Shell mit ausgeführt wird errexitoder wenn diese Zeile die letzte in einer Funktion ist, Switch-Case, was auch immer.
Rudimeier
9
@herve Das hat nichts damit zu tun mkdir; Die Shell erweitert einen solchen Ausdruck zu einer diskreten Liste von Argumenten, an die übergeben wird mkdir.
Chepner
176

Das sollte funktionieren:

$ mkdir -p dir

oder:

if [[ ! -e $dir ]]; then
    mkdir $dir
elif [[ ! -d $dir ]]; then
    echo "$dir already exists but is not a directory" 1>&2
fi

Dadurch wird das Verzeichnis erstellt, wenn es nicht vorhanden ist. Sie werden jedoch gewarnt, wenn der Name des Verzeichnisses, das Sie erstellen möchten, bereits von einem anderen Verzeichnis als einem Verzeichnis verwendet wird.

Alnitak
quelle
Ich glaube nicht, dass es in korn einen -d-Operator gibt, sondern -e wird für beide Dateien / Verzeichnisse verwendet und überprüft nur die Existenz. Außerdem geben alle bei Erfolg 0 zurück, also! ist redundant. Korrigiere mich, wenn ich falsch liege.
Alkar
1
in beiden Punkten falsch, AFAIK. Tests geben bei Erfolg true zurück und -d existiert auch (zumindest unter MacOS X)
Alnitak
5
Es könnte erwähnenswert sein, dass dies nicht ganz threadsicher ist. Zwischen der Zeit, zu der Sie überprüfen, ob das Verzeichnis vorhanden ist, und der Zeit, zu der Sie versuchen zu schreiben, können sich die Dinge ändern.
Justin L.
89

Verwenden Sie das Flag -p.

man mkdir
mkdir -p foo
Jimmyorr
quelle
73

Komplexe Verzeichnisbäume mit einem Befehl definieren

mkdir -p project/{lib/ext,bin,src,doc/{html,info,pdf},demo/stat/a}
Oleg
quelle
Kein Fehler, falls vorhanden, übergeordnete Verzeichnisse nach Bedarf
erstellen
18
Beachten Sie, dass dies keine eigenständige Funktion ist mkdir, sondern die Shell, die den Befehl ausführt. Es heißt Klammererweiterung - AFAIK, nur Bash, ksh, zsh und die C-Shell unterstützen es.
Daniel Kamil Kozar
3
Wenn Sie Leerzeichen um die Kommas haben, können (werden) Sie ein unerwartetes Ergebnis erhalten. In acht nehmen.
Atlas7
1
@ Atlas7 angegeben, müssen Sie Zeichen maskieren, die normalerweise Teil von Regex sind. (dh anstatt zu verwenden folder name, müssen Sie verwenden folder\ name)
John Hamilton
1
Dies ist keine Antwort; Dies ist ein separates Thema, das als Kommentar besser geeignet wäre.
Chris Page
40

Wenn Sie keine Fehlermeldung anzeigen möchten:

[ -d newdir ] || mkdir newdir

Wenn Sie Ihre eigene Fehlermeldung anzeigen möchten:

[ -d newdir ] && echo "Directory Exists" || mkdir newdir
Jahid
quelle
20

Das Alte hat sich bewährt

mkdir /tmp/qq >/dev/null 2>&1

wird tun, was Sie wollen, mit keiner der Rennbedingungen, die viele der anderen Lösungen haben.

Manchmal sind die einfachsten (und hässlichsten) Lösungen die besten.

paxdiablo
quelle
5
Dies schlägt fehl, wenn "tmp" nicht vorhanden war. Es gibt Ihnen auch keine Bestätigung.
Mike Q
15

mkdir foofunktioniert auch wenn das Verzeichnis existiert. Versuchen Sie es mit dem Verzeichnis "foo", wenn das Verzeichnis "foo" nicht vorhanden ist-p Flag, .

Beispiel: -

mkdir -p foo

Dadurch wird das Verzeichnis "foo" nur erstellt, wenn es nicht vorhanden ist. :) :)

Atul Ranjan
quelle
2
Wie von @BrianCampbell erwähnt, werden dadurch auch alle anderen Verzeichnisse im Pfad erstellt. Dies kann gefährlich sein, wenn beispielsweise ein Volume nicht bereitgestellt wird, da möglicherweise Verzeichnisse im Bereitstellungspunkt erstellt werden.
uliwitness
11
directory_name = "foo"

if [ -d $directory_name ]
then
    echo "Directory already exists"
else
    mkdir $directory_name
fi
Visuwa Bharathi K.
quelle
10

Oder wenn Sie zuerst nach der Existenz suchen möchten:

if [[ ! -e /path/to/newdir ]]; then
            mkdir /path/to/newdir
fi

-e ist der existierende Test für Korn Shell.

Sie können auch versuchen, ein Korn-Shell-Handbuch zu googeln.

alkar
quelle
10

mkdir unterstützt -p switch auf Windows 8+ Systemen nicht mehr.

Sie können dies verwenden:

IF NOT EXIST dir_name MKDIR dir_name
Karanvir Kang
quelle
10
Bei OP ging es um AIX kornshell ... nichts mit Windows zu tun, oder?
J. Chomel
9

Siehe Manpage man mkdirfür Option -p

   -p, --parents
          no error if existing, make parent directories as needed

Dadurch werden alle Verzeichnisse in einem bestimmten Pfad erstellt. Wenn vorhanden, wird kein Fehler ausgegeben. Andernfalls werden alle Verzeichnisse im angegebenen Pfad von links nach rechts erstellt. Versuchen Sie den folgenden Befehl. die Verzeichnisse newdirund anotherdirexistiert nicht, bevor dieser Befehl ausgegeben wird

Richtige Benutzung

mkdir -p /tmp/newdir/anotherdir

Nach dem Ausführen des Befehls können Sie unter / tmp sehen newdirund anotherdirerstellen. Sie können diesen Befehl so oft ausgeben, wie Sie möchten exit(0). Aus diesem Grund verwenden die meisten Benutzer diesen Befehl in Shell-Skripten, bevor sie diese tatsächlichen Pfade verwenden.

vkrams
quelle
8

Sie können entweder die if-Schleife verwenden, um zu überprüfen, ob ein Verzeichnis vorhanden ist oder nicht. Wenn es nicht beendet wird, erstellen Sie das Verzeichnis.

1) dir = / home / dir_name

if [ ! -d $dir ]
then
     mkdir $dir
else
     echo "Directory exists"  
fi

2) Sie können ein Verzeichnis verwenden, indem Sie mkdir mit der Option -p verwenden, um ein Verzeichnis zu erstellen. Es wird geprüft, ob das Verzeichnis nicht verfügbar ist.

mkdir -p $dir

Mit mkdir -p kann auch die Baumstruktur des Verzeichnisses erstellt werden. Wenn Sie das übergeordnete und das untergeordnete Verzeichnis mit demselben Befehl erstellen möchten, können Sie mkdir -p auswählen

mkdir -p /home/parent_dir /home/parent_dir/child1 /home/parent_dir/child2
AbhinavVaidya8
quelle
Gibt es einen Vorteil bei der Verwendung der if-Schleife? warum sollte jemand diese über -p Option wählen?!
Pedram Bashiri
1
Ich habe Ihnen Möglichkeiten zum Erstellen der Ordner mitgeteilt, wenn kein Ordner vorhanden ist. Es kommt auf die Anforderung an. Wenn Sie einen Anwendungsfall haben, in dem Sie überprüfen müssen, ob ein Ordner nicht vorhanden ist, und dies nachverfolgen möchten, damit Sie mit Lösung 1 fortfahren können. Wenn dies keine Rolle spielt, können Sie mit Lösung 2 fortfahren, wird der Ordner erstellt wenn nicht vorhanden.
AbhinavVaidya8
Ich habe keine Schleife gesehen.
Amit Naidu
3

Dies ist eine einfache Funktion (Bash-Shell), mit der Sie ein Verzeichnis erstellen können, wenn es nicht vorhanden ist.

#----------------------------------
# Create a directory if it doesn't exist
#------------------------------------
createDirectory() {
    if [ ! -d $1 ]
        then
        mkdir -p $1
    fi
}

Sie können die obige Funktion wie folgt aufrufen:

createDirectory / tmp / fooDir / BarDir

Das obige erstellt fooDir und BarDir, wenn sie nicht existieren. Beachten Sie die Option "-p" im Befehl mkdir, mit der Verzeichnisse rekursiv erstellt werden. Hoffe das hilft.

Balaji Boggaram Ramanarayan
quelle
2
mkdir -p sam
  • mkdir = Verzeichnis erstellen
  • -p = - Eltern
  • (Kein Fehler, falls vorhanden, übergeordnete Verzeichnisse nach Bedarf erstellen)
Paritosh Yadav
quelle
2
if [ !-d $dirName ];then
     if ! mkdir $dirName; then  # Shorter version. Shell will complain if you put braces here though
     echo "Can't make dir: $dirName"
     fi
fi
Alex Zubkov
quelle