Comment mkdir uniquement si un répertoire n'existe pas déjà?

1989

J'écris un script shell à exécuter sous KornShell (ksh) sur AIX. Je voudrais utiliser la mkdircommande pour créer un répertoire. Mais le répertoire existe peut-être déjà, auquel cas je ne veux rien faire. Je veux donc soit tester pour voir que le répertoire n'existe pas, soit supprimer l'erreur "Le fichier existe" qui se mkdirdéclenche lorsqu'il essaie de créer un répertoire existant.

Avez-vous des idées sur la meilleure façon de procéder?

Spike Williams
la source

Réponses:

3296

Essayez mkdir -p:

mkdir -p foo

Notez que cela créera également tous les répertoires intermédiaires qui n'existent pas; par exemple,

mkdir -p foo/bar/baz

va créer des répertoires foo, foo/baret foo/bar/bazs'ils n'existent pas.

Certaines implémentations comme GNU mkdirincluent mkdir --parentsun alias plus lisible, mais cela n'est pas spécifié dans la spécification POSIX / Single Unix et n'est pas disponible sur de nombreuses plates-formes courantes comme macOS, divers BSD et divers Unix commerciaux, il convient donc de l'éviter.

Si vous voulez une erreur lorsque les répertoires parents n'existent pas et que vous souhaitez créer le répertoire s'il n'existe pas, vous pouvez d'abord testpour l'existence du répertoire:

[ -d foo ] || mkdir foo
Brian Campbell
la source
11
l'exemple abrégé que vous utilisez est exactement ce que vous ne devriez pas faire. Il inverse la logique pour économiser de l'espace de codage mais il devrait utiliser! et && et donner plus de sens à ceux qui le lisent.
Mike Q
16
@AndreasLarsen Cette question concerne mkdirles systèmes de type Unix, pas Windows. -pest requis pour la conformité aux spécifications POSIX / Single Unix, donc tout ce qui vise à se conformer à ces spécifications sera pris en charge -p. Windows est entièrement différent, sauf si vous utilisez une couche d'émulation POSIX comme Cygwin ou MSYS.
Brian Campbell,
23
J'ai découvert quelque chose d'intéressant aujourd'hui mkdir -p, vous pouvez utiliser des crochets! {}pour créer une arborescence de répertoires "complexe" dans une commande. Voir ici: technosophos.com/2010/04/15/…
herve
12
@MikeQ Je préférerais ||plutôt que &&parce qu'alors toute la ligne a le bon état de sortie. Important si votre shell fonctionne avec errexitou si cette ligne est la dernière d'une fonction, switch-case, peu importe.
rudimeier
9
@herve Cela n'a rien à voir avec mkdir; le shell étend une telle expression à une liste discrète d'arguments qui sont passés à mkdir.
chepner
177

Cela devrait fonctionner:

$ mkdir -p dir

ou:

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

qui créera le répertoire s'il n'existe pas, mais vous avertira si le nom du répertoire que vous essayez de créer est déjà utilisé par autre chose qu'un répertoire.

Alnitak
la source
Je ne pense pas qu'il y ait un opérateur -d dans korn, plutôt que -e est utilisé pour les fichiers / répertoires et vérifie simplement l'existence. De plus, ils retournent tous 0 en cas de succès, alors! est redondant. Corrige moi si je me trompe.
alkar
1
mal sur les deux points, AFAIK. les tests retournent vrais en cas de succès, et -d existe aussi (au moins sur MacOS X)
Alnitak
5
il convient de mentionner que ce n'est pas tout à fait thread-safe. entre le moment où vous vérifiez si le répertoire existe et le moment où vous essayez d'écrire, les choses peuvent changer.
Justin L.
89

Utilisez l'indicateur -p.

man mkdir
mkdir -p foo
jimmyorr
la source
74

Définir des arborescences de répertoires complexes avec une seule commande

mkdir -p project/{lib/ext,bin,src,doc/{html,info,pdf},demo/stat/a}
Oleg
la source
aucune erreur si existante, créer des répertoires parents selon les besoins
Fedir RYKHTIK
19
Gardez à l'esprit que ce n'est pas une fonctionnalité en mkdirsoi, mais le shell qui exécute la commande. C'est ce qu'on appelle l'expansion de l'accolade - AFAIK, seuls Bash, ksh, zsh et le shell C le prennent en charge.
Daniel Kamil Kozar
3
si vous avez des espaces autour des virgules, vous obtiendrez (obtiendrez) un résultat inattendu. Il faut se méfier.
Atlas7
1
@ Atlas7 a déclaré, vous devrez échapper aux personnages qui font normalement partie de l'expression régulière. (c.-à-d. au lieu d'utiliser, folder namevous devez utiliser folder\ name)
John Hamilton
1
Ce n'est pas une réponse; il s'agit d'un sujet distinct qui serait plus approprié en tant que commentaire.
Chris Page
40

Si vous ne souhaitez afficher aucun message d'erreur:

[ -d newdir ] || mkdir newdir

Si vous souhaitez afficher votre propre message d'erreur:

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

Le vieux éprouvé

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

fera ce que vous voulez avec aucune des conditions de course que beaucoup d'autres solutions ont.

Parfois, les solutions les plus simples (et les plus laides) sont les meilleures.

paxdiablo
la source
5
Cela échouera si "tmp" n'existait pas. cela ne vous donne aucune confirmation.
Mike Q
15

mkdir foofonctionne même si le répertoire existe. Pour le faire fonctionner uniquement si le répertoire nommé "foo" n'existe pas, essayez d'utiliser l' -pindicateur.

Exemple :-

mkdir -p foo

Cela ne créera le répertoire nommé "foo" que s'il n'existe pas. :)

Atul Ranjan
la source
2
Comme mentionné par @BrianCampbell, cela créera également tous les autres répertoires du chemin. Cela peut être dangereux si par exemple un volume est démonté, car il peut créer des répertoires dans le point de montage.
uliwitness
11
directory_name = "foo"

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

Ou si vous voulez d'abord vérifier l'existence:

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

-e est le test existant pour korn shell.

Vous pouvez également essayer de googler un manuel du shell korn.

alkar
la source
10

mkdir ne prend plus en charge le commutateur -p sur les systèmes Windows 8+.

Vous pouvez utiliser ceci:

IF NOT EXIST dir_name MKDIR dir_name
Karanvir Kang
la source
10
OP concernait AIX kornshell ... rien à voir avec Windows, n'est-ce pas?
J. Chomel
9

Se référant à la page man mkdirde manuel pour l'option -p

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

qui créera tous les répertoires dans un chemin donné, s'il existe, ne génère aucune erreur sinon il crée tous les répertoires de gauche à droite dans le chemin donné. Essayez la commande ci-dessous. les répertoires newdiret anotherdirn'existe pas avant d'émettre cette commande

usage correct

mkdir -p /tmp/newdir/anotherdir

Après avoir exécuté la commande, vous pouvez voir newdiret anotherdircréer sous / tmp. Vous pouvez exécuter cette commande autant de fois que vous le souhaitez, la commande a toujours exit(0). Pour cette raison, la plupart des gens utilisent cette commande dans des scripts shell avant d'utiliser ces chemins réels.

vkrams
la source
8

Vous pouvez soit utiliser la boucle if pour vérifier si le répertoire existe ou non, s'il ne se termine pas, créer le répertoire.

1) dir = / home / dir_name

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

2) Vous pouvez utiliser le répertoire mkdir avec l'option -p pour créer un répertoire. Il vérifiera si le répertoire n'est pas disponible.

mkdir -p $dir

mkdir -p permet également de créer l'arborescence du répertoire. Si vous souhaitez créer les répertoires parent et enfant à l'aide de la même commande, vous pouvez choisir mkdir -p

mkdir -p /home/parent_dir /home/parent_dir/child1 /home/parent_dir/child2
AbhinavVaidya8
la source
Y a-t-il un avantage à utiliser la boucle if!? pourquoi quelqu'un choisirait-il cette option surp?!
pedram bashiri
1
Je vous ai expliqué comment créer les dossiers lorsqu'un dossier n'existe pas. Cela dépend de l'exigence de l'un. Si vous avez un cas d'utilisation où vous devez vérifier si le dossier n'existe pas et que vous souhaitez garder une trace de celui-ci afin que vous puissiez aller avec la solution 1. Si cela n'a pas d'importance, vous pouvez aller avec la solution 2, il créera le dossier sinon existe.
AbhinavVaidya8
Je n'ai pas vu de boucle.
Amit Naidu
3

Il s'agit d'une fonction simple (shell bash) qui vous permet de créer un répertoire s'il n'existe pas.

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

Vous pouvez appeler la fonction ci-dessus comme:

createDirectory / tmp / fooDir / BarDir

Ce qui précède crée fooDir et BarDir s'ils n'existent pas. Notez l'option "-p" dans la commande mkdir qui crée récursivement des répertoires. J'espère que cela t'aides.

Balaji Boggaram Ramanarayan
la source
2
mkdir -p sam
  • mkdir = Créer un répertoire
  • -p = --parents
  • (aucune erreur si existante, créez des répertoires parents au besoin)
Paritosh Yadav
la source
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
la source