Throughout my years in the field, I’ve seen that mastering the mkdir command in linux is one of the first skills every user learns. This tool makes the process of creating directories fast, efficient, and powerful. Whether you are a novice organizing personal files or a sysadmin scripting a complex deployment hierarchy, you will find yourself using mkdir daily. This guide covers everything from basic usage to advanced methods like brace expansion, permission management, and real-world DevOps automation topics most articles skip.
If you are new to the terminal, having a solid understanding of basic Linux commands will provide a strong foundation before you dive deep into directory organization
Note:
The mkdir command belongs to GNU Core Utilities and comes installed on all Linux distributions (Ubuntu, Rocky Linux, CentOS, Debian, Fedora and RHEL) so no additional package needs to be downloaded or installed.
Examples
What is the mkdir Command in Linux?
The mkdir command stands for make directory. It is a standard Linux utility used to create one or more new directories inside the file system. You give it a name, it creates the folder. That is the core idea.
The real power of the mkdir command is in its option set. With this command you can build a complex hierarchy of folders using one command. In addition, you can set permissions when creating the directories. Since mkdir allows you to call from within bash scripts to generate your complete project structure programmatically, it is also very important for use in DevOps pipelines where consistency across directory hierarchies matters.
The command is available on all Linux distributions and also works on macOS and other Unix-like systems with minor differences. On Linux, it is part of the GNU coreutils package. You do not need to install anything to use it.
Note:
The mkdir command will not overwrite or delete an existing directory. If a folder with the same name already exists, it will throw an error unless you use the -p flag, which safely skips the error.
Syntax
The basic syntax of the mkdir command is straightforward:
LinuxTeck.com
Here is what each part means:
- [OPTIONS] - Optional flags that modify how the command behaves (like
-p,-m,-v). - DIRECTORY_NAME - The name or path of the directory you want to create. You can pass multiple names in one command.
You can use both relative paths and absolute paths with mkdir. For scripts and automation, absolute paths are always the safer choice because they do not depend on your current working directory.
LinuxTeck.com
mkdir myproject
# Absolute path (creates at exact location)
mkdir /var/www/mysite
# Using $PWD variable for absolute path
mkdir $PWD/logs
Options Table
Here is a quick reference for all the important flags available with the mkdir command:
| OPTION | LONG FORM | DESCRIPTION | EXAMPLE |
|---|---|---|---|
-p
|
--parents
|
Create parent directories as needed. No error if directory already exists. |
|
-m
|
--mode=MODE
|
Set file permission mode at creation time (like chmod syntax). |
|
-v
|
--verbose
|
Print a message for every directory created. |
|
-Z
|
--context
|
Set SELinux security context on created directory (RHEL/Rocky Linux). |
|
--help
|
N/A | Display help information and exit. |
|
--version
|
N/A | Display version information and exit. |
|
Examples
I. Create a Single Directory
The simplest use of mkdir is creating one directory in your current location. Just type the command followed by the folder name you want.
LinuxTeck.com
After running this, use the ls command to verify the directory was created:
LinuxTeck.com
drwxr-xr-x 2 user user 4096 May 11 10:00 myproject
Tip:
Directory names with spaces need to be quoted. Use mkdir "my project" or mkdir my_project (underscores are cleaner for terminal use).
II. Create Multiple Directories at Once
You can create several directories in one command by separating names with spaces. This is much faster than running mkdir four times separately.
LinuxTeck.com
drwxr-xr-x 2 user user 4096 May 11 10:01 config
drwxr-xr-x 2 user user 4096 May 11 10:01 docs
drwxr-xr-x 2 user user 4096 May 11 10:01 images
drwxr-xr-x 2 user user 4096 May 11 10:01 scripts
III. Create Nested Directories with -p Flag
The -p flag is one of the most useful options in mkdir. It tells the command to create all missing parent directories automatically. Without it, if a parent folder does not exist, the command just fails.
LinuxTeck.com
mkdir project/src/components
# With -p it creates all levels automatically
mkdir -p project/src/components
└── src/
└── components/
Tip:
The -p flag also makes mkdir safe to run multiple times in scripts. If the directory already exists, no error is thrown. This is called idempotent behavior and is exactly what you want in automation.
IV. Brace Expansion to Create Structured Directories
Brace expansion is a Bash feature that works perfectly with mkdir. It lets you create multiple subdirectories inside one parent with a single clean command. This is something that almost no tutorial covers properly, but it is a big time saver in real work.
LinuxTeck.com
mkdir -p project/{src,bin,logs,config,docs}
# Multi-level brace expansion
mkdir -p data/{2024,2025}/{01..12}
# Web app structure in one line
mkdir -p webapp/{css,js,images,fonts,pages}
├── bin/
├── config/
├── docs/
├── logs/
└── src/
├── 2024/
│ ├── 01/ ├── 02/ ... └── 12/
└── 2025/
├── 01/ ├── 02/ ... └── 12/
Tip:
The {01..12} syntax uses sequence expansion. You can also use {a..z} or {A,B,C} style lists. This is pure Bash and does not require any extra tools.
V. Set Permissions at Creation Time with -m
The -m flag lets you set directory permissions at the moment of creation, similar to how chmod works in Linux. This is useful when you want to lock down or open up a folder without running a separate chmod command afterward.
LinuxTeck.com
mkdir -m 755 public_html
# Create with 700 (only owner can access)
mkdir -m 700 private_keys
# Create with symbolic permissions
mkdir -m u=rwx,g=rx,o= restricted_dir
drwx------ 2 user user 4096 May 11 10:05 private_keys
Warning:
Avoid using mkdir -m 777 in production environments. World-writable directories are a serious security risk. Always use the least permissive setting your application actually needs.
VI. How umask Interacts with mkdir -m
This is something almost no tutorial explains, and it catches many users off guard. When you use mkdir without the -m flag, the actual permissions applied to the new directory are affected by your system's umask value.
The umask is a mask that removes permission bits from the default. On most Linux systems the default umask is 0022, which means:
- Default directory permissions start at
0777 - umask
0022removes write from group and others - Final effective permissions become
0755
LinuxTeck.com
umask
# See what mkdir creates by default
mkdir testdir && ls -ld testdir
drwxr-xr-x 2 user user 4096 May 11 10:07 testdir
Note:
When you use mkdir -m 777, the umask is bypassed and the exact permission you specify is applied. When you use plain mkdir without -m, the umask is applied. Understanding this difference is important for writing secure scripts.
VII. Verbose Output with -v Flag
The -v flag prints a confirmation message for every directory that gets created. This is useful when running scripts and you want to see exactly what is happening, especially when creating many directories in one go.
LinuxTeck.com
mkdir: created directory 'deploy/app'
mkdir: created directory 'deploy/logs'
mkdir: created directory 'deploy/config'
mkdir: created directory 'deploy/tmp'
VIII. Distro-Specific Behavior (Ubuntu vs Rocky Linux vs CentOS)
The core mkdir behavior is the same across distributions, but there are some practical differences you should know when working across different systems:
| Distro | Default umask | Effective mkdir permissions | SELinux Active? |
|---|---|---|---|
| Ubuntu 24.04 LTS |
|
|
No (AppArmor instead) |
| Rocky Linux 9 |
|
|
Yes (Enforcing by default) |
| CentOS Stream 9 |
|
|
Yes (Enforcing by default) |
On Ubuntu, the default umask for regular users is sometimes set to 0002 (rather than 0022), which gives group members write access. You can check your system's umask with the umask command in your terminal.
LinuxTeck.com
umask
# Rocky / CentOS: umask is typically 0022
umask
Note:
On Rocky Linux 9 and RHEL systems, SELinux is active by default. When you create directories under web roots or system paths, you may need to also set the correct SELinux context. See Example X below for that.
IX. Real Bash Scripts Using mkdir for Project Scaffolding
Using mkdir inside Bash scripts is where it really becomes powerful. You can scaffold entire project structures in seconds. Here are three ready-to-use scripts.
Script 1: Web Project Structure
LinuxTeck.com
# Web project scaffold script
SITE="mywebsite"
mkdir -pv /var/www/$SITE/{public_html,logs,tmp,conf}
mkdir -pv /var/www/$SITE/public_html/{css,js,images,fonts}
echo "Web project structure for $SITE created successfully."
mkdir: created directory '/var/www/mywebsite/public_html'
mkdir: created directory '/var/www/mywebsite/logs'
mkdir: created directory '/var/www/mywebsite/tmp'
mkdir: created directory '/var/www/mywebsite/conf'
mkdir: created directory '/var/www/mywebsite/public_html/css'
mkdir: created directory '/var/www/mywebsite/public_html/js'
mkdir: created directory '/var/www/mywebsite/public_html/images'
mkdir: created directory '/var/www/mywebsite/public_html/fonts'
Web project structure for mywebsite created successfully.
Script 2: DevOps Deployment Pipeline Structure
LinuxTeck.com
# DevOps pipeline directory scaffold
APP="myapp"
BASE="/opt/deployments/$APP"
mkdir -pv $BASE/{releases,shared,current}
mkdir -pv $BASE/shared/{logs,config,tmp,cache}
mkdir -pv $BASE/releases/$(date +%Y%m%d_%H%M%S)
echo "Deployment structure ready at $BASE"
Script 3: Data Science Project Structure
LinuxTeck.com
# Data science project scaffold
PROJECT="ds_project"
mkdir -pv $PROJECT/{data,notebooks,models,output,scripts,docs}
mkdir -pv $PROJECT/data/{raw,processed,external}
mkdir -pv $PROJECT/output/{figures,reports}
echo "$PROJECT directory structure ready."
Tip:
Always use mkdir -p in scripts instead of plain mkdir. The -p flag prevents the script from failing if any directory already exists, making your scripts safe to run multiple times.
X. SELinux Context on Rocky Linux and RHEL (Enterprise Linux)
On Rocky Linux 9, RHEL 9, and CentOS Stream 9, SELinux runs in enforcing mode by default. When you create directories under system paths like /var/www/, the new directory inherits the SELinux context of the parent. But sometimes this is not the right context for your application, and services like Apache will fail to access the directory even with correct Unix permissions.
The -Z flag in mkdir lets you apply the default SELinux context at creation time:
LinuxTeck.com
sudo mkdir -Z /var/www/newsite
# Verify the SELinux context
ls -Z /var/www/
If the inherited context is still wrong after creation, use semanage fcontext and restorecon to fix it permanently:
LinuxTeck.com
sudo semanage fcontext -a -t httpd_sys_content_t "/var/www/newsite(/.*)?"
sudo restorecon -Rv /var/www/newsite
Warning:
On Rocky Linux and RHEL, if Apache or Nginx cannot read a newly created directory even with correct Unix permissions (755), SELinux context is almost always the cause. Always check with ls -Z first before disabling SELinux.
XI. mkdir in DevOps and CI/CD Pipelines
The mkdir command shows up constantly in real DevOps workflows. Here is how it is used across common tools:
GitHub Actions:
LinuxTeck.com
- name: Prepare deployment directories
run: |
mkdir -p dist/{assets,fonts,css,js}
mkdir -p /tmp/build_artifacts
Ansible (using the file module equivalent of mkdir -p):
LinuxTeck.com
- name: Create app directories
ansible.builtin.file:
path: /opt/myapp/{{ item }}
state: directory
mode: "0755"
loop:
- logs
- config
- tmp
Jenkins Pipeline (Declarative):
LinuxTeck.com
stage('Prepare Workspace') {
steps {
sh 'mkdir -p build/{artifacts,reports,logs}'
}
}
XII. Troubleshooting Common mkdir Errors
Here are the most common errors you will run into with mkdir, along with the exact cause and how to fix each one.
Error 1: Permission Denied
LinuxTeck.com
Cause: You do not have write permission on the parent directory.
Fix: Use sudo if you have admin rights, or create the directory in a location where you have write access.
LinuxTeck.com
Error 2: File Exists; use -p to skip safely
LinuxTeck.com
Error 3: No Such File or Directory add -p to create all parents
LinuxTeck.com
Error 4: No Space Left on Device, check disk with df
LinuxTeck.com
/dev/sda1 20G 20G 0 100% /
If the filesystem is at 100%, you need to clear space. Use the df command to check disk usage and identify what is filling the drive, then free space or extend your volume before retrying.
Quick Reference Cheat Sheet
Here is a complete cheat sheet for the mkdir command with all flags and practical one-liners. Bookmark this for daily use.
| Command | What It Does |
|---|---|
|
Create a single directory in the current location |
|
Create multiple directories at once |
|
Create nested directories including all missing parents |
|
Create multiple subdirectories inside one parent using brace expansion |
|
Create multi-level nested structure with sequences |
|
Create directory with specific permissions (bypasses umask) |
|
Create directory with verbose confirmation output |
|
Create nested directories with verbose output for each level |
|
Create directory in system path using root privileges |
|
Create directory with default SELinux context (Rocky/RHEL) |
|
Create directory using absolute path via $PWD variable |
|
Create directory in script with error handling fallback |
Interview Questions on mkdir
These are commonly asked during Linux sysadmin and DevOps interviews. If you are preparing for a certification or a job interview, these questions are worth knowing well. For a broader set of questions, check out the Linux shell scripting interview questions guide.
Interview Q&A
Q1: What is the difference between mkdir dir and mkdir -p dir?
Plain mkdir dir creates a single directory and fails with an error if any parent in the path does not exist, or if the directory already exists. The mkdir -p dir form creates all missing parent directories automatically and does not throw an error if the target directory already exists. The -p flag is the right choice for scripts and automation because it is safe to run multiple times without failure.
Q2: How does umask affect the permissions of a directory created with mkdir?
When you run mkdir without the -m flag, the system applies a umask to the default directory permission of 0777. A umask of 0022 (common on most systems) removes write permission from group and others, resulting in effective permissions of 0755. When you use mkdir -m MODE, the umask is bypassed and the exact mode you specify is applied to the directory.
Q3: How do you create a directory structure for multiple years and months in one command?
You can use brace expansion combined with mkdir -p to achieve this. The command mkdir -p data/{2024,2025}/{01..12} creates directories for each month of 2024 and 2025 inside a parent data folder. The {01..12} part is a sequence expansion handled by Bash itself, not by mkdir directly.
Q4: On Rocky Linux, you created a directory under /var/www/ but Apache cannot access it even with 755 permissions. Why?
This is almost always a SELinux context issue. Rocky Linux 9 runs SELinux in enforcing mode by default. The newly created directory may have inherited the wrong SELinux type from its parent. You need to check with ls -Z /var/www/ and then use semanage fcontext combined with restorecon to apply the correct httpd_sys_content_t label. Alternatively, use mkdir -Z at creation time to apply the default context.
Q5: How would you use mkdir inside a Bash script to safely set up a project structure that can run multiple times without errors?
Always use mkdir -p inside scripts. It will create all directories if they do not exist and skip them silently if they already exist. You can also add error handling with mkdir -p /path/to/dir || { echo "Failed to create directory"; exit 1; }. Combining -p with -v gives you verbose confirmation in logs. Using brace expansion like mkdir -p app/{logs,config,tmp} lets you scaffold complete structures in one line.
Why the mkdir Command Matters
On the surface, the mkdir command may appear simple, but it forms an important foundation for organizing Linux file systems properly. Every web server setup starts with creating the right directory structure, while Bash automation scripts depend on directories to store output. In the same way, DevOps pipelines rely on folder layouts that remain predictable and consistent across different environments.
Knowing only mkdir dirname is enough to get started. However, understanding options like -p, brace expansion, permission control, and SELinux contexts puts you in the category of someone capable of writing production-ready scripts and reliable server configurations. These practical details are often what separate a beginner from a working sysadmin.
The distro differences matter in the real world too. A script that works fine on Ubuntu might break silently on Rocky Linux because of SELinux, or produce different permissions because of a different default umask. Understanding these gaps helps you write scripts that are portable and predictable across environments.
For anyone learning Linux in 2025 or 2026, getting comfortable with mkdir in all its forms is a foundational step. It shows up in every Linux role, from junior admin to senior DevOps engineer. If you are building your skills, the Linux commands for beginners guide is a great next step to continue that journey.
Key Takeaways
- The
mkdircommand creates one or more directories and is available on all Linux distributions without any installation. - The
-pflag creates all missing parent directories and makesmkdirsafe to run multiple times in scripts without errors. - Brace expansion (
mkdir -p project/{src,bin,logs}) lets you scaffold full directory trees in a single command, which no other tutorial covers well. - The
-mflag sets exact permissions at creation time and bypasses the system umask, unlike plainmkdirwhich respects the umask. - On Rocky Linux 9 and RHEL systems, SELinux context affects directory access even when Unix permissions are correct. Use
mkdir -Zandrestoreconto handle this. - Ubuntu and Rocky Linux differ in their default umask settings for regular users, which can affect the actual permissions applied to new directories.
- In DevOps pipelines (GitHub Actions, Jenkins, Ansible),
mkdir -pis the standard pattern for preparing workspace directories safely. - All four common errors (Permission denied, File exists, No such file or directory, No space left) have clear causes and simple fixes once you understand what is happening.
People Also Ask
What does mkdir -p do in Linux?
The mkdir -p command creates a directory and all missing parent directories in the given path automatically. For example, mkdir -p a/b/c creates folders a, a/b, and a/b/c even if none of them exist. It also suppresses the error that would normally appear if the directory already exists, making it safe to use inside scripts that run multiple times.
How do you create multiple directories at once in Linux?
You can create multiple directories in one command by listing their names separated by spaces: mkdir dir1 dir2 dir3. For creating multiple subdirectories inside a single parent, use brace expansion: mkdir -p project/{css,js,images,docs}. This creates four subdirectories inside project with one command.
How do I create a directory with specific permissions using mkdir?
Use the -m flag followed by the permission mode: mkdir -m 755 mydir. This sets the permissions at creation time and bypasses the system umask. You can use numeric (octal) notation like 755 or symbolic notation like u=rwx,g=rx,o=rx. Avoid using 777 in production as it makes the directory writable by everyone on the system.
Why does mkdir fail with "No such file or directory" error?
This error means one or more parent directories in the path you specified do not exist yet. For example, mkdir a/b/c fails if a or a/b do not exist. The fix is to add the -p flag: mkdir -p a/b/c. This tells mkdir to create all the missing parent directories automatically before creating the target directory.
How do I use mkdir in a Bash script without it failing if the directory exists?
Always use mkdir -p inside Bash scripts. Without -p, running the script twice will cause a "File exists" error on the second run. With -p, mkdir checks if the directory already exists and simply does nothing if it does, allowing the script to run cleanly every time. For added safety in critical scripts, use: mkdir -p /path/to/dir || { echo "Failed"; exit 1; }. You can refer to the Official Linux mkdir Man Page.
Does mkdir work the same on Ubuntu and Rocky Linux?
The core behavior is the same, but there are important differences. Rocky Linux 9 runs SELinux in enforcing mode by default, which can block access to newly created directories under system paths even if Unix permissions are correct. Ubuntu uses AppArmor instead of SELinux. Additionally, the default umask for regular users can differ between distros. Ubuntu desktop installs sometimes use a umask of 0002 while Rocky Linux typically uses 0022, resulting in different default permissions on new directories.
From your first terminal command to advanced sysadmin skills every guide here is written in plain English with real examples you can run right now.