How to mkdir only if a directory does not already exist?
Solution 1
Try mkdir -p
:
mkdir -p foo
Note that this will also create any intermediate directories that don't exist; for instance,
mkdir -p foo/bar/baz
will create directories foo
, foo/bar
, and foo/bar/baz
if they don't exist.
Some implementation like GNU mkdir
include mkdir --parents
as a more readable alias, but this is not specified in POSIX/Single Unix Specification and not available on many common platforms like macOS, various BSDs, and various commercial Unixes, so it should be avoided.
If you want an error when parent directories don't exist, and want to create the directory if it doesn't exist, then you can test
for the existence of the directory first:
[ -d foo ] || mkdir foo
Solution 2
This should work:
$ mkdir -p dir
or:
if [[ ! -e $dir ]]; then
mkdir $dir
elif [[ ! -d $dir ]]; then
echo "$dir already exists but is not a directory" 1>&2
fi
which will create the directory if it doesn't exist, but warn you if the name of the directory you're trying to create is already in use by something other than a directory.
Solution 3
Use the -p flag.
man mkdir
mkdir -p foo
Solution 4
Defining complex directory trees with one command
mkdir -p project/{lib/ext,bin,src,doc/{html,info,pdf},demo/stat/a}
Solution 5
If you don't want to show any error message:
[ -d newdir ] || mkdir newdir
If you want to show your own error message:
[ -d newdir ] && echo "Directory Exists" || mkdir newdir
![Spike Williams](https://i.stack.imgur.com/rfrFT.jpg?s=256&g=1)
Spike Williams
Of all the code I've written in my life, probably the javascript eight ball I wrote on a lark one night over a decade ago is the thing that's had the most impact in the world. So it goes.
Updated on July 08, 2022Comments
-
Spike Williams almost 2 years
I am writing a shell script to run under the KornShell (ksh) on AIX. I would like to use the
mkdir
command to create a directory. But the directory may already exist, in which case I do not want to do anything. So I want to either test to see that the directory does not exist, or suppress the "File exists" error thatmkdir
throws when it tries to create an existing directory.How can I best do this?
-
Alnitak about 15 yearswrong on both counts, AFAIK. tests return true on success, and -d exists too (at least on MacOS X)
-
Mike Q about 10 yearsThis will fail if "tmp" did not exist. nor does it give you any confirmation.
-
Mike Q about 10 yearsthe shortened example you use is exactly what you should not do. It is reversing the logic to save coding space but it should use ! and && and make more sense to those reading it.
-
angularsen over 9 yearsOn Windows8 it seems -p is no longer supported and it's the default behavior.
-
Brian Campbell over 9 years@AndreasLarsen This question is about
mkdir
on Unix-like systems, not on Windows.-p
is required for POSIX/Single Unix Specification compliance, so anything that intents to comply with those specifications will support-p
. Windows is entirely different, unless you use a POSIX emulation layer like Cygwin or MSYS. -
Justin L. over 9 yearsit might be worth mentioning that this isn't quite thread-safe. between the time that you check if the directory exists and the time you try to write, things might change.
-
uliwitness about 9 yearsAs mentioned by @BrianCampbell, this will also create any other directories in the path. This can be dangerous if e.g. a volume becomes unmounted, as it may create directories in the mount point.
-
herve over 8 yearsI discovered something interesting today with
mkdir -p
, you can use brackets!{}
to create "complex" directory tree in a command. See here: technosophos.com/2010/04/15/… -
rudimeier over 8 years@MikeQ I 'd prefer
||
instead of&&
because then the whole line has the right exit status. Important if your shell runs witherrexit
or if that line is the last one in a function, switch-case, whatever. -
Zsigmond Lőrinczy over 8 yearsOr:
mkdir somedir 2>/dev/null || true
-
Fedir RYKHTIK about 8 yearsno error if existing, make parent directories as needed
-
Daniel Kamil Kozar about 8 yearsKeep in mind that this is not a feature of
mkdir
itself, but the shell that executes the command. It's called brace expansion - AFAIK, only Bash, ksh, zsh, and the C shell support it. -
J. Chomel about 7 yearsOP was about AIX kornshell... nothing to do with Windows, does it?
-
Atlas7 almost 7 yearsif you have spaces around the commas you may (will) get unexpected result. Beware.
-
chepner over 6 years@herve That has nothing to do with
mkdir
; the shell expands such an expression to a discrete list of argument that are passed tomkdir
. -
John Hamilton over 6 years@Atlas7 stated, you will need to escape characters that are normally part of regex. (i.e. instead of using
folder name
you need to usefolder\ name
) -
pedram bashiri almost 6 yearsIs there any advantage in using if loop!? why would someone choose that over -p option?!
-
AbhinavVaidya8 almost 6 yearsI have shared you ways of creating the folders when an folder does not exists. It depends upon the requirement on the one. If you have a use case where you need to check if folder does not exist and you want to keep track of that so you can go with solution 1. If it does not matter, you can go with solution 2, it will create the folder if not exists.
-
akozi almost 6 yearsDoes this work with a wild card before the intermediate steps? Ex /*/foo/bar/baz ?
-
Brian Campbell over 5 years@akozi Yes, if the appropriate directories already exist at the level that the wild card is used. In the shell, glob expansion happens before passing the arguments to the program (
mkdir
, in this case). So if you had directoriesa
,b
, andc
,mkdir -p */foo/bar/baz
would be the same asmkdir -p a/foo/bar/baz b/foo/bar/baz c/foo/bar/baz
.mkdir
can take multiple arguments, and when given-p
, it will create needed intermediate directories. Experiment with this yourself. Tryecho mkdir -p */foo/bar/baz
to see what command is run; or just try running it in a test directory. -
Chris Page over 4 yearsThis is not an answer; this is a separate topic that would be more appropriate as a comment.
-
Peter Mortensen about 4 yearsRace conditions? Can you elaborate in your answer? Non-atomic test & create?
-
Peter Mortensen about 4 yearsDefining? Do you mean creating?
-
Peter Mortensen about 4 years
-
Peter Mortensen about 4 yearsAre you sure it was supported before? Do you have a source?
-
paxdiablo about 4 years@Peter, a snippet like (for example)
[ -d newdir ] || mkdir newdir
, where the directory does not initially exist, has a race condition in that, between the test for existence and the attempted creation, another process could swoop in and create the directory. Hence themkdir
would then fail. -
Jahid about 4 years@PeterMortensen : Of course. Use
mkdir -p
if you do not want race conditions. But you won't get to show your ownDirectory exists
error. -
RicarHincapie almost 4 years@herve discovery is very handy. Please remember not to leave whitespaces in any part of this script.
-
Shankara Narayana about 3 years-p, --parents no error if existing, make parent directories as needed
-
hakre about 3 years@Mike Q: the base path
/tmp
has likely been chosen in the example to represent a base-path that always exists and is write-able to the current user, e.g. the user has enough rights to create a directory in. You raise a valid point thought:: the logic is a bit contradictory, as when this command fails, it can mean two things: 1.) the directory exists or 2.) the directory could not be created. This is not true for the operation itself, therefore a simple post-check on the directory path can give the confirmation, or the next command that operates on. -
edoardesd over 2 yearsIt should be: mkdir -p /my/new/dir >/dev/null 2>&1
-
Leevi L over 2 years
mkdir -p my/new/dir
does not complain ifmy/new/dir
already exists, no need to redirect output -
moodboom over 2 yearsTypo fixed. Leevi, I believe I ran into a situation where the output needed to be squelched.
-
Jesse Nickles over 2 years
mkdir -p /tmp/qq > /dev/null 2>&1
will create /tmp/ if missing. -
dube about 2 yearsnote for naiive windows users:
-p
still fails on windows when the folder exists -
Jeppe about 2 years@herve Awesome! Just realized it works for other commands as well, e.g. to create 3 files:
touch {a,b,c}.txt