MKDIR ricorsivo


307

Esiste un comando linux che sto trascurando che rende possibile fare qualcosa del tipo: (pseudo)

$ mkdir -R foo/bar/zoo/andsoforth

O non c'è alternativa se non quella di creare le directory una alla volta?



1
divertente, stavo guardando quella pagina ma trascuravo totalmente il "genitore" perché li pensavo come bambini (da sinistra a destra).

18
Protip: in alcune shell puoi persino fare mkdir -p foo/{bar,baz}/zoo/andsoforth. Molto utile!
Aaron Copley il

1
Personalmente, ho trascurato "genitore" anche nella pagina man perché, beh, penso che la bandiera dovrebbe essere "-r" per "ricorsivo" - o almeno, dovrebbe esserci un alias per tale dato che mkdirha solo 6 bandiere documentate in totale. Inferno, mi sento come se il comando dovesse creare ricorsivamente le directory di default, e se non lo vuoi, dovresti specificare così esplicitamente.
jbowman,

Risposte:


513
$ mkdir -p foo/bar/zoo/andsoforth

93
FYI the -p sta per "genitori"
carl crott il

14
Avrebbero potuto creare -r invece, come qualsiasi altro comando, è impossibile ricordare parametri specifici per ogni comando di Linux
Vedmant

2
Ma mkdir -pnon è multipiattaforma, non funziona in tutte le shell
Роман Коптев

9
@ РоманКоптев, mkdir -pè specificato in POSIX , che è la cosa più vicina ad essere completamente portatile. Cosa meglio ti aspetti da uno script di shell?
Wildcard il

5
@StephanBijzitter Sì, questo è unix.se, non unixandwindows.se. :)
SEE

16

L'utilizzomkdir -p è un modo semplice per la maggior parte dei sistemi operativi moderni:

mkdir -p foo/bar/zoo/andsoforth

Tuttavia, mkdir -pnon è raccomandato in molti manuali. Leggi la documentazione di GNU makee autoconfsui problemi con l'utilizzo di mkdir -p:

I sistemi di installazione e configurazione multipiattaforma hanno le loro alternativemkdir -p sicure per .

CMake da usare nella riga di comando della shell:

 cmake -E make_directory foo/bar/zoo/andsoforth

Configurazione automatica da utilizzare nello script con preelaborazione:

AS_MKDIR_P(foo/bar/zoo/andsoforth)

o:

AC_PROG_MKDIR_P(foo/bar/zoo/andsoforth)

Ma queste soluzioni richiedono cmakeo autoconf( M4) strumenti da installare (e l'eventuale pre-elaborazione)

Puoi usare anche lo install-shscript con l' -dopzione:

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

Questo script è utilizzato da autoconfe automakeproject. Penso che debba essere la soluzione più sicura.

Al momento stavo cercando una soluzione multipiattaforma per standard /bin/shsenza dipendenze, ma non ne ho trovata una. Pertanto ho scritto il prossimo script che potrebbe non essere l'ideale, ma penso che sia conforme alla maggior parte dei requisiti multipiattaforma :

#! /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
}

Questo script può essere utilizzato per vecchi sistemi, dove l'opzione -pper mkdirè assente.

sedla versione multipiattaforma basata su è dirnamestata aggiunta al codice. Funziona in modo simile a dirname(correggi con percorso /, percorsi con solo nome di base, percorsi con trailing /, percorsi con e senza trailing \ns). Questa funzione non può funzionare correttamente se il percorso ha nuovi caratteri o alcuni caratteri non validi per la locale corrente. Sostituisce anche qualsiasi combinazione di /( //, ///) con singolo/

La linea modificata mkdir "$1" || return 1in test -d "$1" || { mkdir "$1" || return 1; }perché mkdirtermina con errore se esiste un percorso e questo controllo è necessario per percorsi contenenti costruzioni come aaa\.(se aaanon esiste la versione precedente crea aaae quindi tenta di crearla di nuovo).

Questa versione di mkd non genera un errore se esiste già un percorso (ma ha ancora la possibilità di generare tale errore nell'esecuzione parallela) e non può ottenere diverse directory nella riga di comando.


4
"mkdir -p" è definito da posix. Quali varianti unix o unix-like non lo supportano? (e non dovrebbe essere una shell integrata, anche se immagino non ci sia alcun motivo per cui non potrebbe essere.) pubs.opengroup.org/onlinepubs/9699919799/utilities/mkdir.html
Tim B

5
Alcune delle informazioni in quella pagina hanno solo 15 anni. Alcuni sono più vecchi.
Thomas Dickey,

7
I sistemi che non supportano mkdir -psarebbero troppo vecchi (e stiamo parlando di almeno un paio di decenni) per avere printfun'utilità o un supporto --per segnare la fine delle opzioni.
Stéphane Chazelas,

2
Il tuo cdirnamedarebbe la risposta sbagliata per foo/bar//, o nomi di directory che contiene i caratteri di nuova riga, o caratteri non validi nella localizzazione corrente.
Stéphane Chazelas,

2
printfè sicuro sui sistemi POSIX. Supporto per sistemi POSIX mkdir -p. mkdir -pè stato specificato da POSIX per decenni. --ha iniziato a diffondersi sui sistemi AT&T a partire dal SysIII nella prima metà degli anni '80. printfapparve per la prima volta come un kshbuiltin credo ed è stato specificato da POSIX più tardi mkdir -p. Alcune shell POSIX (come pdksh o yash based) non hanno ancora printfincorporato.
Stéphane Chazelas,

0

Opzione -pal comando mkdirrende p directory Arent come necessario (nessun errore se esistente):

mkdir -p foo/bar/zoo/andsoforth

Un altro modo è, ad esempio, usare &&(errore se esiste la cartella specificata):

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

L'operatore di concatenamento &&viene utilizzato per concatenare i comandi insieme, in modo tale che il comando successivo venga eseguito se e solo se il comando precedente è uscito senza errori.

Certo, il primo modo è migliore.


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

Questo dovrebbe farlo.

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.