web-dev-qa-db-fra.com

mkdir -p échoue quand le répertoire existe

Sur l'un de nos systèmes distants, mkdir -p $directory échoue lorsque le répertoire existe. ce qui signifie que ça se voit 

mkdir: impossible de créer le répertoire '$ directory': le fichier existe

C'est vraiment curieux, car je croyais que le contrat de -p était toujours réussi lorsque le répertoire existe déjà. Et cela fonctionne sur les autres systèmes que j'ai essayés.

il existe un utilisateur test sur tous ces systèmes, et directory=/home/test/tmp.

22
UmNyobe

Cela pourrait être causé s'il y a déjà un fichier du même nom situé dans le répertoire.

Edit: Notez qu'un répertoire ne peut pas contenir à la fois un fichier et un dossier du même nom sur les machines Linux.

31
Ryan Tse

Vérifiez s'il existe un fichier (pas un répertoire) portant le même nom que $ répertoire.

5
DWright

mkdir -p ne créera pas de répertoire s'il existe un fichier du même nom dans le même répertoire. Sinon, cela fonctionnera comme prévu.

2
ASHU

Votre répertoire était-il un montage réseau basé sur Fuse - par hasard?

En plus d’un fichier avec ce nom déjà existant (autre réponse), cela peut se produire lorsqu’un processus Fuse qui montait quelque chose dans ce répertoire s’arrêtait (ou était tué, par exemple avec kill -9 ou via Linux Tueur OOM).

Pour voir ce qui se passe en détail, exécutez strace -fy mkdir -p $directory, qui affiche tous les appels système impliqués et leurs valeurs de retour.


Je considère les messages d'erreur émis dans ce cas comme un bogue dans mkdir -p (en particulier la bibliothèque gnulib):

Lorsque vous l'exécutez dans un répertoire sur lequel un processus Fuse a été monté mais ce processus s'est bloqué, il est indiqué

mkdir: cannot create directory ‘/mymount’: File exists

ce qui est plutôt hautement inexact, parce que l'appel stat() sous-jacent call renvoie ENOTCONN (Transport endpoint is not connected); mais mkdir propage l'erreur moins spécifique de la précédente mkdir() sycall . C'est très déroutant, car la page de manuel dit:

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

il ne devrait donc pas y avoir d'erreur si le répertoire existe, mais ls -l / affiche:

d????????? ? ?    ?       ?            ? files

donc, selon ceci (d), il est un répertoire, mais ce n'est pas selon test -d.


Je crois qu'un meilleur message d'erreur (que mkdir -p devrait émettre dans ce cas) serait:

mkdir: cannot create directory ‘/mymount’: Transport endpoint is not connected
0
nh2