Categories
aix ksh mkdir scripting shell

How to mkdir only if a directory does not already exist?

2578

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 that mkdir throws when it tries to create an existing directory.

How can I best do this?

0

    4240

    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
    

    11

    • 12

      the 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.

      – Mike Q

      Jun 16, 2014 at 17:36

    • 21

      @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.

      Oct 9, 2014 at 15:54

    • 41

      I 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/…

      – herve

      Feb 4, 2016 at 11:13

    • 16

      @MikeQ I ‘d prefer || instead of && because then the whole line has the right exit status. Important if your shell runs with errexit or if that line is the last one in a function, switch-case, whatever.

      – rudimeier

      Mar 13, 2016 at 15:42


    • 10

      @herve That has nothing to do with mkdir; the shell expands such an expression to a discrete list of argument that are passed to mkdir.

      – chepner

      Oct 31, 2017 at 20:33

    229

    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.

    3

    • I don’t think there’s a -d operator in korn, rather -e is used for both files / directories and just checks existence. Also, they all return 0 upon success, so ! is redundant. Correct me if I’m wrong.

      – alkar

      Apr 27, 2009 at 14:57

    • 1

      wrong on both counts, AFAIK. tests return true on success, and -d exists too (at least on MacOS X)

      – Alnitak

      Apr 27, 2009 at 14:58

    • 6

      it 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.

      – Justin L.

      Mar 12, 2015 at 1:27

    107

    Use the -p flag.

    man mkdir
    mkdir -p foo
    

    1

    • 5

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

      May 2, 2021 at 7:29