Linux mkdir Command
last modified October 23, 2026
The mkdir (make directory) command creates directories. It can
create one or several directories at once, build a whole path of nested
directories, and set the permissions of the new directories.
The syntax is mkdir [options] directory.... The examples use
GNU mkdir from coreutils 9.1 with Bash 5.2. The most important
options are -p (create parents, no error if the directory
exists), -m (set the mode), and -v (print each
created directory).
Creating a directory
With a single argument, mkdir creates one directory in the
current working directory.
mkdir projects ls -ld projects
mkdir prints nothing on success. The -d option of
ls lists the directory itself instead of its contents. The new
directory is owned by the user who created it, and its permissions come from
the umask, which is covered later.
$ mkdir projects $ ls -ld projects drwxr-xr-x 2 jano jano 4096 Oct 23 13:22 projects
Creating multiple directories
Each argument is a separate directory.
mkdir docs images scripts ls
The three directories are created in the order given. If one of them cannot
be created, mkdir reports an error, continues with the rest, and
exits with a non-zero status.
$ mkdir docs images scripts $ ls docs images projects scripts
When the directory already exists
Creating a directory that already exists is an error, unless the
-p option is used.
mkdir docs echo $? mkdir -p docs echo $?
Without -p, the command fails with exit status 1. With
-p, an existing directory is silently accepted. This makes
mkdir -p the usual choice in scripts that may run more than
once.
$ mkdir docs mkdir: cannot create directory ‘docs’: File exists $ echo $? 1 $ mkdir -p docs $ echo $? 0
Creating nested directories
By default, all parent directories of the new directory must exist. The
-p (--parents) option creates the missing parents.
mkdir app/src/main mkdir -p app/src/main tree app
The first command fails because app and app/src
do not exist. The second creates all three levels in one step.
$ mkdir app/src/main
mkdir: cannot create directory ‘app/src/main’: No such file or directory
$ mkdir -p app/src/main
$ tree app
app
└── src
└── main
3 directories, 0 files
Verbose output
The -v (--verbose) option prints a message for
each directory that is created.
mkdir -pv website/{css,js,img}
mkdir -pv website/css
The braces are expanded by the shell, not by mkdir:
website/{css,js,img} becomes three arguments. With
-p, the parent website is created first and also
reported. The second command prints nothing, because
website/css already exists and no directory was created.
$ mkdir -pv website/{css,js,img}
mkdir: created directory 'website'
mkdir: created directory 'website/css'
mkdir: created directory 'website/js'
mkdir: created directory 'website/img'
$ mkdir -pv website/css
Creating a directory tree with brace expansion
Brace expansion can produce many paths from a short pattern. Combined with
-p, a whole tree is created at once.
mkdir -p backup/2026/{01..03}/{logs,db}
The sequence {01..03} expands to 01 02 03 with the
leading zeros kept, and each month gets a logs and a
db directory. To preview the paths, put echo in
front of the command.
$ mkdir -p backup/2026/{01..03}/{logs,db}
$ tree backup
backup
└── 2026
├── 01
│ ├── db
│ └── logs
├── 02
│ ├── db
│ └── logs
└── 03
├── db
└── logs
11 directories, 0 files
Setting permissions
New directories get the mode 777 minus the bits set in the umask. The
-m (--mode) option sets the mode explicitly, in
numeric or symbolic form.
umask mkdir default mkdir -m 700 secret mkdir -m u=rwx,g=rx,o= shared ls -ld default secret shared
With the umask 0022, a plain mkdir creates the directory with
mode 755 (rwxr-xr-x). The secret directory is
accessible only by its owner, and shared can be entered and
listed by the group but not by others. Setting the mode at creation avoids
the short window during which a directory created first and changed later
with chmod has the default permissions.
$ umask 0022 $ mkdir default $ mkdir -m 700 secret $ mkdir -m u=rwx,g=rx,o= shared $ ls -ld default secret shared drwxr-xr-x 2 jano jano 4096 Oct 23 13:22 default drwx------ 2 jano jano 4096 Oct 23 13:22 secret drwxr-x--- 2 jano jano 4096 Oct 23 13:22 shared
Mode and parent directories
When -m is combined with -p, the mode applies only
to the last directory in the path.
mkdir -p -m 700 vault/keys/ssh ls -ld vault vault/keys vault/keys/ssh
The parents vault and vault/keys get the default
mode from the umask. If all levels must be private, set a stricter umask in
a subshell, for example (umask 077; mkdir -p vault/keys/ssh),
or run chmod on each level.
$ mkdir -p -m 700 vault/keys/ssh $ ls -ld vault vault/keys vault/keys/ssh drwxr-xr-x 3 jano jano 4096 Oct 23 13:22 vault drwxr-xr-x 3 jano jano 4096 Oct 23 13:22 vault/keys drwx------ 2 jano jano 4096 Oct 23 13:22 vault/keys/ssh
Names with spaces
The shell splits arguments on spaces, so a directory name with spaces must be quoted or escaped.
mkdir My Documents ls -d My Documents rmdir My Documents mkdir "My Documents" 'Old Files' Tax\ 2026 ls -d My* Old* Tax*
The unquoted command creates two directories, My and
Documents, which are removed again with rmdir.
Double quotes, single quotes, and a backslash before the space all produce a
single name. In scripts, always quote variables: mkdir -p
"$dir".
$ mkdir My Documents $ ls -d My Documents Documents My $ rmdir My Documents $ mkdir "My Documents" 'Old Files' Tax\ 2026 $ ls -d My* Old* Tax* My Documents Old Files Tax 2026
Common errors
These are the errors you are most likely to see with mkdir.
touch notes mkdir notes mkdir notes/drafts mkdir /opt/myapp sudo mkdir /opt/myapp sudo chown jano: /opt/myapp ls -ld /opt/myapp
A directory cannot have the same name as an existing file, and a file cannot
be used as a parent directory. Creating a directory requires write
permission on the parent directory; /opt is owned by root, so
the directory is created with sudo and then handed over to the
regular user with chown.
$ touch notes $ mkdir notes mkdir: cannot create directory ‘notes’: File exists $ mkdir notes/drafts mkdir: cannot create directory ‘notes/drafts’: Not a directory $ mkdir /opt/myapp mkdir: cannot create directory ‘/opt/myapp’: Permission denied $ sudo mkdir /opt/myapp $ sudo chown jano: /opt/myapp $ ls -ld /opt/myapp drwxr-xr-x 2 jano jano 4096 Oct 23 13:22 /opt/myapp
Temporary directories
For scratch work in scripts, use mktemp -d instead of
mkdir with a fixed name.
dir=$(mktemp -d) echo "$dir" ls -ld "$dir" rmdir "$dir"
mktemp -d creates a directory with a unique random name under
/tmp and mode 700, and prints its path. A fixed name such as
/tmp/work can collide with another run of the script or be
created in advance by another user.
$ dir=$(mktemp -d) $ echo "$dir" /tmp/tmp.Vz6FNryKg1 $ ls -ld "$dir" drwx------ 2 jano jano 4096 Oct 23 13:22 /tmp/tmp.Vz6FNryKg1 $ rmdir "$dir"
Using mkdir in a script
The script creates the layout of a new project. It can be run repeatedly and reports a failure.
#!/bin/bash
# create the directory layout of a new project; safe to run repeatedly
project=${1:-demo}
if ! mkdir -p "$project"/{src,tests,docs}; then
echo "cannot create $project" >&2
exit 1
fi
echo "created $project"
Because of -p, the second run succeeds without changing
anything. When the target exists as a regular file, mkdir fails
once for each of the three paths, the if ! branch prints a
message, and the script exits with status 1.
$ bash mkdirs.sh webapp created webapp $ bash mkdirs.sh webapp created webapp $ tree webapp webapp ├── docs ├── src └── tests 4 directories, 0 files $ touch report $ bash mkdirs.sh report mkdir: cannot create directory ‘report’: Not a directory mkdir: cannot create directory ‘report’: Not a directory mkdir: cannot create directory ‘report’: Not a directory cannot create report $ echo $? 1
Best practices for mkdir
- Use -p in scripts: It creates missing parents and does not fail when the directory exists.
- Set the mode at creation: Use
-mfor private directories; remember that it applies only to the last level. - Quote names: Quote directory names and variables that may contain spaces.
- Preview brace expansions: Put
echoin front of a complexmkdircommand to see the generated paths. - Use mktemp for scratch space:
mktemp -dgives a unique, private directory.
Source
In this article, we have used the mkdir command to create single
and nested directories, set their permissions, handle names with spaces, and
create directories safely in scripts.
Author
List all Linux tutorials.