mkdir récursif

307

Existe-t-il une commande linux que je néglige, qui permet de faire quelque chose dans le sens de: (pseudo)

$ mkdir -R foo/bar/zoo/andsoforth

Ou n'y a-t-il pas d'autre solution que de créer les répertoires un à un?

Braiam
la source
1
C'est drôle, je regardais cette page, mais je négligeais totalement le mot "parent" parce que je les pensais comme des enfants (de gauche à droite).
18
Protip: Dans certaines coquilles, vous pouvez même faire mkdir -p foo/{bar,baz}/zoo/andsoforth. Très utile!
Aaron Copley
1
Personnellement, j'ai également omis de mentionner "parent" dans la page de manuel car, eh bien, je pense que le drapeau devrait être "-r" pour "récursif" - ou tout au moins, il devrait y avoir un pseudonyme, car mkdir6 drapeaux documentés au total. Bon sang, j'ai l'impression que la commande devrait créer des répertoires de manière récursive par défaut, et si vous ne le souhaitez pas, vous devrez le spécifier explicitement.
jbowman
1
stackoverflow.com/questions/1731767/…
Ciro Santilli Il y a 16 jours

Réponses:

514
$ mkdir -p foo/bar/zoo/andsoforth
EEAA
la source
93
FYI the -p signifie "parents"
carl crott
14
Ils auraient pu faire -r à la place, comme toute autre commande, il est impossible de se rappeler des paramètres spécifiques pour chaque commande linux
Vedmant
2
Mais ce mkdir -pn'est pas cross-plateforme, ne fonctionne pas dans chaque shell
Роман Коптев
9
@ РоманКоптев, mkdir -pest spécifié dans POSIX , qui est la chose la plus proche d'être totalement portable. Que voulez-vous de mieux dans un script shell?
Wildcard
5
@StephanBijzitter Oui, c'est unix.se, pas unixandwindows.se. :)
EEAA
16

Utilisermkdir -p est un moyen simple pour la plupart des systèmes d’exploitation modernes:

mkdir -p foo/bar/zoo/andsoforth

Cependant, mkdir -pn'est pas recommandé dans de nombreux manuels. Lisez la documentation de GNU makeet autoconfsur les problèmes d'utilisation de mkdir -p:

Les systèmes d’installation et de configuration multiplate-forme ont leurs propres alternativesmkdir -p sûres pour .

CMake à utiliser en ligne de commande shell:

 cmake -E make_directory foo/bar/zoo/andsoforth

Autoconf à utiliser dans un script avec prétraitement:

AS_MKDIR_P(foo/bar/zoo/andsoforth)

ou:

AC_PROG_MKDIR_P(foo/bar/zoo/andsoforth)

Mais ces solutions nécessitent cmakeou autoconf( M4) des outils à installer (et un prétraitement possible)

Vous pouvez également utiliser le install-shscript avec l' -doption:

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

Ce script est utilisé par autoconfet par automakeprojet. Je pense que ce doit être la solution la plus sûre.

À l'époque, je cherchais une solution multiplateforme pour des applications standard /bin/shsans dépendances, mais je n'en ai pas trouvé. J'ai donc écrit le prochain script qui n'est peut-être pas idéal, mais je pense qu'il est conforme à la plupart des exigences multi-plateformes :

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

Ce script peut être utilisé pour les anciens systèmes, où l’option -ppour mkdirest absente.

sedUne version multiplateforme basée sur X a dirnameété ajoutée au code. Cela fonctionne avec une méthode similaire à dirname(correct avec chemin /, chemins avec nom de base uniquement, chemins avec fin /, chemins avec et sans fin \n). Cette fonction ne peut pas fonctionner correctement si le chemin contient des nouvelles lignes ou des caractères non valides pour les paramètres régionaux en cours. Il remplace également toute combinaison de /( //, ///) avec un seul/

Ligne modifiée mkdir "$1" || return 1en test -d "$1" || { mkdir "$1" || return 1; }raison de la mkdirfin de l'erreur si le chemin existe et que cette vérification est nécessaire pour les chemins contenant des constructions telles que aaa\.(Si la aaaversion précédente n'existe pas, la création est créée aaa, puis essaye de la recréer).

Cette version de mkd ne génère pas d'erreur si le chemin existe déjà (mais elle a toujours la possibilité de générer une telle erreur lors d'une exécution parallèle) et ne peut pas obtenir plusieurs répertoires en ligne de commande.

Роман Коптев
la source
4
"mkdir -p" est défini par posix. Quelles variantes Unix ou Unix-like ne le supporte pas? (et ce ne devrait pas être un shell intégré, bien que je suppose qu'il n'y a aucune raison pour que ce ne soit pas le cas.) pubs.opengroup.org/onlinepubs/9699919799/utilities/mkdir.html
Tim B
5
Certaines des informations contenues dans cette page ont seulement 15 ans. Certains sont plus âgés.
Thomas Dickey
7
Les systèmes qui ne prendraient pas en charge mkdir -pseraient trop anciens (et nous parlons d’au moins deux décennies) pour avoir un printfutilitaire ou une assistance --permettant de marquer la fin des options.
Stéphane Chazelas
2
Votre cdirnameréponse serait incorrecte foo/bar//ou les noms de répertoires contenant des caractères de nouvelle ligne ou des caractères non valides dans les paramètres régionaux en cours.
Stéphane Chazelas
2
printfest sécurisé sur les systèmes POSIX. Prise en charge des systèmes POSIX mkdir -p. mkdir -pPOSIX le spécifie depuis des décennies. --a commencé à se généraliser sur les systèmes AT & T à partir de SysIII au début des années 80. printfest apparu pour la première fois en tant que kshcode intégré et a été spécifié par POSIX plus tard mkdir -p. Certains shells POSIX (comme pdksh ou yash) ne sont toujours pas printfintégrés.
Stéphane Chazelas
0

Option -pde commande mkdirfait p répertoires ARENT au besoin (pas d' erreur si existant):

mkdir -p foo/bar/zoo/andsoforth

Une autre méthode consiste, par exemple, à utiliser &&(erreur si le dossier spécifié existe):

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

L'opérateur de chaînage &&est utilisé pour chaîner des commandes, de telle sorte que la commande suivante soit exécutée si et seulement si la commande précédente s'est terminée sans erreur.

Bien sûr, le premier moyen est meilleur.

Simhumileco
la source
-3
mkdir foo foo/bar foo/bar/zoo/ foo/bar/zoo/andsofort.

Cela devrait le faire.

Kanchan Kumar
la source