Is there a linux command that I'm overlooking that makes it possible to do something along the lines of: (pseudo)

$ mkdir -R foo/bar/zoo/andsoforth

Or is there no alternative but to make the directories one at a time?

migrated from serverfault.com Sep 27 '12 at 3:56

This question came from our site for system and network administrators.

  • 4
    linux.die.net/man/1/mkdir – Zoredache Aug 7 '12 at 20:36
  • 1
    funny, I was looking at that page but totally overlooked "parent" because I was thinking of them as children (left to right). – Dr.Dredel Aug 7 '12 at 20:37
  • 17
    Protip: In some shells you can even do mkdir -p foo/{bar,baz}/zoo/andsoforth. Very useful! – Aaron Copley Aug 7 '12 at 20:43
  • 1
    Personally, I overlooked "parent" in the man page as well because, well, I feel like the flag should be "-r" for "recursive" - or at the very least, there should be an alias for such since mkdir has only 6 documented flags in total. Hell, I feel like the command should create directories recursively by default, and if you don't want this then you should have to specify so explicitly. – jbowman May 13 '16 at 18:03
  • 1
up vote 415 down vote accepted
$ mkdir -p foo/bar/zoo/andsoforth
  • 76
    FYI the -p stands for "parents" – carl crott Apr 22 '15 at 17:06
  • 10
    They could've made -r instead, like any other command, that's impossible to remember specific parameters for every linux command – Vedmant Mar 21 '16 at 2:56
  • 2
    But mkdir -p is not cross platform, doesn't work in every shell – Роман Коптев Apr 17 '16 at 13:40
  • 6
    @РоманКоптев, mkdir -p is specified in POSIX, which is the closest thing to being fully portable. What better do you expect in a shell script? – Wildcard Apr 18 '16 at 18:54
  • 3
    @StephanBijzitter Yep, this is unix.se, not unixandwindows.se. :) – EEAA Oct 5 '16 at 19:21

Using of mkdir -p is a more simple way for most modern oses:

mkdir -p foo/bar/zoo/andsoforth

However, using of mkdir -p is not recommended in many manuals. Read documentation for the latest versions of gnu make and autoconf about problems with using mkdir -p:

The cross platform installation and configuration systems have theirs own safe alternatives for mkdir -p.

CMake to use in shell command line:

 cmake -E make_directory foo/bar/zoo/andsoforth

Autoconf to use in script with preprocessing:

AS_MKDIR_P(foo/bar/zoo/andsoforth)

or:

AC_PROG_MKDIR_P(foo/bar/zoo/andsoforth)

But these solutions require cmake or autoconf (M4) tools to be installed (and possible preprocessing)

You can use also install-sh script with -d option:

install-sh -d foo/bar/zoo/andsoforth

This script is used by autoconf and automake project. I think it must be the most safe solution.

At the time I was searching for cross platform solution for standard /bin/sh without dependences, but haven't found one. Therefore I wrote the next script that may be not ideal, but I think it is compliant to most cross platform requirements:

#! /bin/sh

cdirname() # cross platform alternative for 'dirname'
{
  # $1 - path
  test $# -eq 1 || { echo "Procedure 'cdirname' must have only one parameter. Scripting error."; exit 1; }
  echo "$1" | sed -n -e '1p' | sed  -e 's#//*#/#g' -e 's#\(.\)/$#\1#' -e 's#^[^/]*$#.#' -e 's#\(.\)/[^/]*$#\1#' -
}

mkd() # cross platform alternative for 'mkdir -p'
{
  # $1 - directory to create
  test $# -eq 1 || { echo "Function 'mkd' can create only one directory (with it's parent directories)."; exit 1; }
  test -d "$1"  && return 0
  test -d "$(cdirname "$1")" || { mkd "$(cdirname "$1")" || return 1; }
  test -d "$1" || { mkdir "$1" || return 1; }
  return 0
}

This script can be used for old systems, where option -p for mkdir is absent.

sed-based cross platform version of dirname was added to the code. It works with a way similar to dirname (correct with path /, paths with base name only, paths with trailing /, paths with and without trailing \ns). This function can't work correct if the path has newlines or some invalid characters for current locale. It also replaces any combination of / (//, ///) with single /

Changed line mkdir "$1" || return 1 to test -d "$1" || { mkdir "$1" || return 1; } because mkdir terminates with error if path exists and this check is needed for paths containing constructions like aaa\. (If aaa doesn't exist previous version creates aaa and then tries to create it again).

This version of mkd doesn't generate error if path already exist (but it still has the possibility to generate such an error in parallel execution) and can't get several directories in command line.

  • 4
    "mkdir -p" is defined by posix. What unix or unix-like variants don't support it? (and it shouldn't be a shell built-in, though I guess there isn't any reason it couldn't be.) pubs.opengroup.org/onlinepubs/9699919799/utilities/mkdir.html – Tim B Apr 17 '16 at 22:49
  • 4
    Some of the information in that page is only 15 years old. Some is older. – Thomas Dickey Apr 17 '16 at 23:30
  • 7
    Systems that wouldn't support mkdir -p would be too old (and we're talking at least a couple of decades old) to have a printf utility or support -- to mark the end of options. – Stéphane Chazelas Apr 18 '16 at 14:06
  • 2
    Your cdirname would give the wrong answer for foo/bar//, or directory names containing newline characters, or invalid characters in the current locale. – Stéphane Chazelas Apr 18 '16 at 14:12
  • 2
    printf is safe on POSIX systems. POSIX systems support mkdir -p. mkdir -p has been specified by POSIX for decades. -- started to be widespread on AT&T systems starting with SysIII in the early-mid-80s. printf first appeared as a ksh builtin I believe and was specified by POSIX later than mkdir -p. Some POSIX shells (like pdksh or yash based) still don't have printf builtin. – Stéphane Chazelas Apr 18 '16 at 14:28

Option -p in command mkdir makes parent directories as needed (no error if existing):

mkdir -p foo/bar/zoo/andsoforth

Another way is, for example using && (error if the specified folder exists):

mkdir foo && mkdir foo/bar && mkdir foo/bar/zoo && mkdir foo/bar/zoo/andsoforth

The chaining operator && is used to chain commands together, such that the next command is run if and only if the preceding command exited without errors.

Of course, the first way is better.

mkdir foo foo/bar foo/bar/zoo/ foo/bar/zoo/andsofort.

This should do it.

protected by Archemar Dec 20 '17 at 8:38

Thank you for your interest in this question. Because it has attracted low-quality or spam answers that had to be removed, posting an answer now requires 10 reputation on this site (the association bonus does not count).

Would you like to answer one of these unanswered questions instead?