Files and directories
mkdir
Create directories, optionally with all missing parents.
mkdir [OPTION...] DIRECTORY...
mkdir creates each directory named on the command line. Without options it is strict: the
parent must already exist and the directory itself must not, otherwise it fails with an error.
mkdir -p is the form scripts use. It creates every missing parent along the path and treats
"already exists" as success, so it can run again and again safely. Pair it with brace expansion
to lay out a whole project tree in one line.
New directories get mode 0777 minus your umask (typically 755 or 775). -m sets the
mode directly, which avoids a short window where the directory exists with looser permissions.
Examples
Create a directory
mkdir reports
ls -ld reports
drwxr-xr-x 2 dev dev 2 Oct 31 20:20 reports
The new directory gets mode drwxr-xr-x here: 777 minus this shell's umask of 022.
Create several directories at once
mkdir drafts archive tmp
ls -d */
archive/ data/ drafts/ logs/ photos/ scripts/ src/ tmp/
Each argument is a separate directory. ls -d */ lists only directories, so the three new
ones appear among the fixture's own.
Creating a directory that already exists
mkdir data
mkdir: cannot create directory ‘data’: File exists
Plain mkdir treats an existing directory as an error and exits with 1.
Creating a directory whose parent is missing
mkdir build/output/logs
mkdir: cannot create directory ‘build/output/logs’: No such file or directory
Without -p, mkdir only creates the last component, and build/output does not exist yet.
Create a whole path with -p
mkdir -p build/output/logs
mkdir -p build/output/logs
find build
build build/output build/output/logs
-p creates build, build/output and build/output/logs in order. The second run does
nothing and still succeeds, which makes mkdir -p safe to repeat in scripts.
See what was created
mkdir -pv data/2026/march
mkdir: created directory 'data/2026' mkdir: created directory 'data/2026/march'
-v prints one line per directory actually created. data already existed, so only the two
new levels are reported.
Lay out a project tree in one command
mkdir -p webapp/{src/{api,ui},tests,docs}
tree webapp
webapp ├── docs ├── src │ ├── api │ └── ui └── tests 6 directories, 0 files
This is bash brace expansion, not a mkdir feature: the shell turns the pattern into
webapp/src/api webapp/src/ui webapp/tests webapp/docs before mkdir runs, and -p
creates webapp and webapp/src on the way.
Create a private directory
mkdir -m 700 secrets
ls -ld secrets
drwx------ 2 dev dev 2 Oct 31 20:20 secrets
-m 700 gives the owner full access and everyone else none, set at creation time rather
than with a separate permission change afterwards.
Names with spaces
mkdir "tax returns" old\ photos
ls -d */
data/ logs/ old photos/ photos/ scripts/ src/ tax returns/
Quotes or a backslash keep the space inside one argument. Without them, mkdir tax returns
would create two directories, tax and returns.
A directory named after today's date
d=backups/$(date +%F)
mkdir -p "$d" && echo "created $d"
created backups/2026-10-31
date +%F prints YYYY-MM-DD, a name that also sorts chronologically. The date in the
output is the day this page was built.
Common pitfalls
mkdir -pwith a typo (mkdir -p /var/wwww/site) silently creates the wrong tree. Check the path before relying on-p.-mapplies only to the last directory; parents created by-pget the default umask-based mode.mkdir dir && cd diris so common that many people definemkcd() { mkdir -p -- "$1" && cd -- "$1"; }in their~/.bashrc.
GNU vs BSD and macOS
The examples above ran the GNU/Linux version. These are the differences that matter on macOS and the BSDs (written from their documentation, not run here).
-p,-mand-vwork on both GNU and BSD/macOS. The long forms (--parents,--mode,--verbose) are GNU-only.
Options worth knowing
A selection, described in our own words. For the full list, see mkdir(1) or mkdir --help.
| Option | What it does |
|---|---|
-p, --parents | Create missing parents; no error if the directory exists. |
-m, --mode MODE | Set the permission mode of the new directory. |
-v, --verbose | Print a line for each directory created. |
-Z | Set the default SELinux security context on the new directories. |
Related
rmdirRemove empty directories, and refuse if they are not empty.mktempCreate a temporary file or directory with a unique, unpredictable name and print that name.installCopy files into place and set their mode, owner and group in one step; can also create directories.touchUpdate a file's timestamps, creating it empty if it does not exist.umaskShow or set the mask that removes permission bits from newly created files and directories.- Brace expansionGenerate lists of words with {a,b,c} and sequences with {1..10} and {01..10..2}, why {1..$n} does not work, and how braces differ from globs.
- QuotingSingle quotes, double quotes, backslashes and $'...', what each protects, and the unquoted-variable bugs they prevent, each shown failing and then fixed.