2788 votes

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

Je suis en train d'écrire un shell script à exécuter sous KornShell (ksh) sur AIX. J'aimerais utiliser le mkdir pour créer un répertoire. Mais le répertoire peut déjà exister, auquel cas je ne veux rien faire. Je veux donc soit vérifier que le répertoire n'existe pas, soit supprimer l'erreur "File exists" que la commande mkdir se lance lorsqu'il essaie de créer un répertoire existant.

Comment puis-je m'y prendre ?

4550voto

Brian Campbell Points 101107

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

créera des répertoires foo , foo/bar y foo/bar/baz s'ils n'existent pas.

Certaines implémentations comme GNU mkdir inclure mkdir --parents comme un 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 communes comme macOS, divers BSD et divers Unix commerciaux, il faut donc l'éviter.

Si vous voulez une erreur lorsque les répertoires parents n'existent pas, et si vous voulez créer le répertoire s'il n'existe pas, alors vous pouvez test pour l'existence du répertoire en premier :

[ -d foo ] || mkdir foo

13 votes

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 avoir plus de sens pour ceux qui le lisent.

2 votes

Sous Windows8, il semble que -p ne soit plus supporté et que ce soit le comportement par défaut.

24 votes

@AndreasLarsen Cette question porte sur mkdir sur les systèmes de type Unix, pas sur Windows. -p est requis pour la conformité à la spécification POSIX/Single Unix, donc tout ce qui a l'intention de se conformer à ces spécifications supportera -p . Windows est totalement différent, à moins que vous n'utilisiez une couche d'émulation POSIX comme Cygwin ou MSYS.

248voto

Alnitak Points 143355

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.

0 votes

Je ne pense pas qu'il y ait un opérateur -d dans korn, plutôt -e est utilisé pour les deux fichiers / répertoires et vérifie juste l'existence. De plus, ils retournent tous 0 en cas de succès, donc ! est redondant. Corrigez-moi si je me trompe.

1 votes

Faux sur les deux points, AFAIK. tests retour vrai en cas de succès, et -d existe aussi (au moins sur MacOS X)

7 votes

Il peut être utile de mentionner que ceci n'est pas tout à fait sûr au niveau du thread. entre le moment où vous vérifiez si le répertoire existe et le moment où vous essayez d'écrire, les choses peuvent changer.

114voto

jimmyorr Points 3004

Utilisez l'option -p.

man mkdir
mkdir -p foo

6 votes

-p, --parents pas d'erreur si existant, crée les répertoires parents si nécessaire

91voto

Oleg Points 101

Définition d'arborescences de répertoires complexes avec une seule commande

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

0 votes

Pas d'erreur si existant, créer des répertoires parents si nécessaire

27 votes

Gardez à l'esprit qu'il ne s'agit pas d'une fonctionnalité de l'application mkdir mais le shell qui exécute la commande. C'est ce que l'on appelle l'expansion des accolades - AFAIK, seuls Bash, ksh, zsh et le shell C le supportent.

4 votes

Si vous avez des espaces autour des virgules, vous pouvez (allez) obtenir un résultat inattendu. Attention.

27voto

paxdiablo Points 341644

Le vieux truc qui a fait ses preuves

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

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

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

6 votes

Cette opération échouera si "tmp" n'existe pas. Elle ne vous donne pas non plus de confirmation.

0 votes

Conditions de course ? Pouvez-vous préciser votre réponse ? Test et création non atomiques ?

3 votes

@Peter, un extrait comme (par exemple) [ -d newdir ] || mkdir newdir où le répertoire n'existe pas à l'origine, il y a une condition de course dans la mesure où, entre le test d'existence et la tentative de création, un autre processus pourrait intervenir et créer le répertoire. Par conséquent, le mkdir échouerait alors.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X