Come mkdir solo se una directory non esiste già?


1988

Sto scrivendo uno script di shell da eseguire sotto KornShell (ksh) su AIX. Vorrei usare il mkdircomando per creare una directory. Ma la directory potrebbe già esistere, nel qual caso non voglio fare nulla. Quindi voglio testare per vedere se la directory non esiste, o sopprimere l'errore "File esiste" che viene generato mkdirquando si tenta di creare una directory esistente.

Qualche idea sul modo migliore per farlo?

Risposte:


3295

Prova mkdir -p:

mkdir -p foo

Si noti che ciò creerà anche eventuali directory intermedie che non esistono; per esempio,

mkdir -p foo/bar/baz

creerà directory fooe foo/bar, foo/bar/bazse non esistono.

Alcune implementazioni come GNU mkdirincludono mkdir --parentsun alias più leggibile, ma questo non è specificato nelle specifiche POSIX / Single Unix e non è disponibile su molte piattaforme comuni come macOS, vari BSD e vari Unix commerciali, quindi dovrebbe essere evitato.

Se si desidera un errore quando non esistono directory principali e si desidera creare la directory se non esiste, è possibile prima testl'esistenza della directory:

[ -d foo ] || mkdir foo

11
l'esempio abbreviato che usi è esattamente ciò che non dovresti fare. Sta invertendo la logica per risparmiare spazio di codifica ma dovrebbe usare! e && e ha più senso per coloro che lo leggono.
Mike Q,

16
@AndreasLarsen Questa domanda riguarda i mkdirsistemi simili a Unix, non quelli Windows. -pè richiesto per la conformità alle specifiche POSIX / Single Unix, pertanto sarà supportato tutto ciò che intende conformarsi a tali specifiche -p. Windows è completamente diverso, a meno che non si utilizzi un livello di emulazione POSIX come Cygwin o MSYS.
Brian Campbell,

22
Ho scoperto qualcosa di interessante oggi con mkdir -p, puoi usare le parentesi! {}per creare un albero di directory "complesso" in un comando. Vedi qui: technosophos.com/2010/04/15/…
herve

12
Preferirei @MikeQ ||invece che &&perché l'intera linea ha il giusto stato di uscita. Importante se la tua shell funziona con errexito se quella linea è l'ultima in una funzione, switch-case, qualunque cosa.
rudimeier,

9
@herve Che non ha nulla a che fare con mkdir; la shell espande tale espressione in un elenco discreto di argomenti a cui viene passato mkdir.
Chepner,

177

Questo dovrebbe funzionare:

$ mkdir -p dir

o:

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

che creerà la directory se non esiste, ma ti avverte se il nome della directory che stai cercando di creare è già in uso da qualcosa di diverso da una directory.


Non penso che ci sia un operatore -d in korn, piuttosto -e viene usato per entrambi i file / directory e controlla solo l'esistenza. Inoltre, tutti restituiscono 0 in caso di successo, quindi! è ridondante. Correggimi se sbaglio.
alkar,

1
sbagliato su entrambi i fronti, AFAIK. i test tornano veri in caso di successo e -d esiste anche (almeno su MacOS X)
Alnitak,

5
vale la pena ricordare che questo non è abbastanza sicuro per i thread. tra il momento in cui controlli se esiste la directory e il momento in cui provi a scrivere, le cose potrebbero cambiare.
Justin L.


74

Definizione di alberi di directory complessi con un comando

mkdir -p project/{lib/ext,bin,src,doc/{html,info,pdf},demo/stat/a}

nessun errore, se esistente, crea le directory principali secondo necessità
Fedir RYKHTIK

19
Tieni presente che questa non è una caratteristica di mkdirse stessa, ma la shell che esegue il comando. Si chiama espansione di parentesi graffe: AFAIK, solo Bash, ksh, zsh e la shell C lo supportano.
Daniel Kamil Kozar,

3
se hai spazi attorno alle virgole potresti (otterrai) risultati imprevisti. Attenzione.
Atlas7,

1
@ Atlas7 ha dichiarato, sarà necessario sfuggire ai personaggi che normalmente fanno parte di regex. (cioè invece di usare folder namedevi usare folder\ name)
John Hamilton

1
Questa non è una risposta; questo è un argomento separato che sarebbe più appropriato come commento.
Chris Page

40

Se non vuoi mostrare alcun messaggio di errore:

[ -d newdir ] || mkdir newdir

Se vuoi mostrare il tuo messaggio di errore:

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

20

Il vecchio provato e vero

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

farà quello che vuoi in nessuna delle condizioni di gara di molte altre soluzioni.

A volte le soluzioni più semplici (e più brutte) sono le migliori.


5
Questo fallirà se "tmp" non esistesse. né ti dà alcuna conferma.
Mike Q,

15

mkdir foofunziona anche se la directory esiste. Per farlo funzionare solo se la directory denominata "pippo" non esiste, prova a usare il -pflag.

Esempio :-

mkdir -p foo

Questo creerà la directory denominata "pippo" solo se non esiste. :)


2
Come menzionato da @BrianCampbell, questo creerà anche qualsiasi altra directory nel percorso. Questo può essere pericoloso se, ad esempio, un volume viene smontato, poiché può creare directory nel punto di montaggio.
uliwitness

11
directory_name = "foo"

if [ -d $directory_name ]
then
    echo "Directory already exists"
else
    mkdir $directory_name
fi

10

O se vuoi prima verificare l'esistenza:

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

-e è il test esistente per la shell korn.

Puoi anche provare a cercare su google un manuale di shell korn.


10

mkdir non supporta più -p switch su sistemi Windows 8+.

Puoi usare questo:

IF NOT EXIST dir_name MKDIR dir_name

10
OP parlava di AIX kornshell ... niente a che fare con Windows, vero?
J. Chomel,

9

Facendo riferimento alla pagina man man mkdirper l'opzione -p

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

che creerà tutte le directory in un determinato percorso, se esiste non genera alcun errore, altrimenti crea tutte le directory da sinistra a destra nel percorso specificato. Prova il comando seguente. le directory newdire anotherdirnon esiste prima di emettere questo comando

uso corretto

mkdir -p /tmp/newdir/anotherdir

Dopo aver eseguito il comando puoi vedere newdire anotherdircreare sotto / tmp. È possibile emettere questo comando tutte le volte che lo si desidera, il comando ha sempre exit(0). Per questo motivo la maggior parte delle persone usa questo comando negli script di shell prima di usare quei percorsi effettivi.


8

Puoi usare if loop per verificare se la directory esiste o no, se non esce che crea la directory.

1) dir = / home / nome_dir

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

2) È possibile utilizzare la directory mkdir con l'opzione -p per creare una directory. Controllerà se la directory non è disponibile lo farà.

mkdir -p $dir

mkdir -p permette anche di creare la struttura ad albero della directory. Se vuoi creare le directory padre e figlio usando lo stesso comando, puoi optare per mkdir -p

mkdir -p /home/parent_dir /home/parent_dir/child1 /home/parent_dir/child2

C'è qualche vantaggio nell'utilizzare if loop !? perché qualcuno dovrebbe scegliere quell'opzione over -p ?!
Pedram Bashiri,

1
Ti ho condiviso i modi per creare le cartelle quando non esiste una cartella. Dipende dal requisito da quello. Se hai un caso d'uso in cui devi controllare se la cartella non esiste e vuoi tenerne traccia in modo da poter andare con la soluzione 1. Se non importa, puoi andare con la soluzione 2, creerà la cartella se non esiste.
AbhinavVaidya8,

Non ho visto un ciclo.
Amit Naidu,

3

Questa è una semplice funzione (bash shell) che ti permette di creare una directory se non esiste.

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

È possibile chiamare la funzione sopra come:

createDirectory / tmp / fooDir / BarDir

Quanto sopra crea fooDir e BarDir se non esistono. Nota l'opzione "-p" nel comando mkdir che crea ricorsivamente directory. Spero che sia di aiuto.


2
mkdir -p sam
  • mkdir = Crea directory
  • -p = --parents
  • (nessun errore se esistente, crea le directory principali secondo necessità)

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
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.