mkdir -p fails when directory exists
Asked Answered
Z

6

39

On one of our remote systems mkdir -p $directory fails when the directory exists. which means it shows

mkdir: cannot create directory '$directory' : file exists

This is really puzzling, as I believed the contract of -p was that is always succeed when the directory already exists. And it works on the other systems I tried.

there is a user test on all of these systems, and directory=/home/test/tmp.

Zwinglian answered 24/1, 2013 at 8:30 Comment(0)
N
53

This could be caused if there is already a file by the same name located in the directory.

Note that a directory cannot contain both a file and folder by the same name on linux machines.

Noisome answered 24/1, 2013 at 8:33 Comment(2)
that's exactly what is was and I am currently reviewing and fixing our scriptsZwinglian
Thanks. In my case it was failing because there was a sym link with the same name.Barbie
B
4

Check to see if there is a file (not a directory) with a name same as $directory.

Bodycheck answered 24/1, 2013 at 8:35 Comment(0)
T
4

mkdir -p won't create directory if there is a file with the same name is existing in the same directory. Otherwise it will work as expected.

Tancred answered 24/1, 2013 at 14:30 Comment(0)
J
4

Was your directory a FUSE-based network mount by any chance?

In addition to a file with that name already existing (other answer), this can happen when a FUSE process that once mounted something at this directory crashed (or was killed, e.g. with kill -9 or via the Linux OOM killer).

Check in mount if the FUSE mount is still listed there. If yes, you should be able to unmount it and fix the situation using fusermount -uz.

To see what is happening in detail, run strace -fy mkdir -p $directory, which shows all syscalls involved and their return values.


I consider the error messages emitted in this case a bug in mkdir -p (in particular the gnulib library):

When you run it on a dir that had a FUSE process mounted but that process crashed, it says

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

which is rather highly inaccurate, because the underlying stat() call returns ENOTCONN (Transport endpoint is not connected); but mkdir propagates up the less-specific error from the previous mkdir() sycall. It's extra confusing because the man page says:

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

so it shouldn't error if the dir exists, yet ls -l / shows:

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

so according to this (d), it is a directory, but it isn't according to test -d.


I believe a better error message (which mkdir -p should emit in this case) would be:

mkdir: cannot create directory ‘/mymount’: Transport endpoint is not connected
Jena answered 14/12, 2018 at 20:29 Comment(2)
if this is the case, what's the fix?Levasseur
@Levasseur To fix: Check in mount if the FUSE mount is still listed there. If yes, you should be able to unmount it and fix the situation using fusermount -uz. I've added that to the answer now.Jena
C
0

Reason: file named -p already exists.

Explanation: You may wonder how a file -p is created when you only created a directory.It's because everything in Unix is a file,even directories you create is a file.

Solution: Method 1: rename existing directory ('-p' in your case)

sudo mv -p -p/renaming

we have moved -p into a new directory -p/renaming or say renamed it. Now, rerun the command

mkdir -p

There should be no errors this time.

Another problem you may encounter: Permission Denied This occurs when you do not have the write permission you can check by using

ls -lad -p

you will see something like this the 'd' indicates this is a directory and r-x indicates the user has only permission to read/execute but no permission to write so to give permission to the user, use:

chmod u+w -p

Now try again

ls -lad -p

and you will see The user has now permission to write

Now, you can create the directory

mkdir -p
Chemotropism answered 22/7, 2023 at 2:37 Comment(0)
R
0

I had a similar situation where the directory clearly wasn't there. I was using bash under WSL and the directory was a Windows share. There was a background process that was started in that folder. I had done an rm -rf from another shell to delete the directory and suddenly my scripts stopped working. After I did a ps -ef to locate the process started in that directory, I was able to kill -9 <pid> and then mkdir worked.

Richmond answered 4/7 at 14:46 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.