The mkdir command creates directories from the command line, handling everything from single folders to complex nested structures with a single command. Whether you’re organizing project files, setting up server directory trees, or scripting automated deployments, mkdir gives you precise control over directory creation and permissions without touching a file manager.
You’ll learn how to create single and multiple directories, build nested directory structures with parent directories in one step, set specific permissions during creation, handle spaces in directory names, and integrate mkdir into scripts using features like brace expansion. By understanding mkdir’s core options and practical patterns, you can structure file systems efficiently and automate directory setup tasks.
Understand the mkdir Command
If you’re new to mkdir, think of it as the foundation for organizing your Linux filesystem. It creates the folders that hold your files, scripts, logs, and configuration data. Every directory you see was created either manually with mkdir or programmatically by software that calls the same underlying system function.
Basic Syntax Breakdown
The mkdir command follows this structure:
mkdir [OPTIONS] DIRECTORY_NAME...
- mkdir: The command itself, short for “make directory”.
- [OPTIONS]: Optional flags that modify behavior (permissions, parent creation, verbose output).
- DIRECTORY_NAME: One or more directory names to create. Separate multiple names with spaces.
At its simplest, mkdir project creates a directory named project in your current location. You can create multiple directories at once by listing them: mkdir docs src tests creates three separate directories.
Common Options Reference
The most useful mkdir options organized by task:
| Task | Option | What It Does |
|---|---|---|
| Create parent directories | -p, --parents | Creates missing parent directories automatically; doesn’t error if directory exists |
| Set permissions at creation | -m MODE, --mode=MODE | Sets permissions using octal (755) or symbolic (u=rwx,g=rx,o=rx) notation |
| See what mkdir is doing | -v, --verbose | Prints a message for each directory created |
| Get help | --help | Displays usage information and all available options |
| Check version | --version | Shows mkdir version (part of GNU coreutils package) |
The -p option is particularly powerful. It handles nested directory creation without requiring you to create each level manually, and it prevents errors when a directory already exists, making it ideal for scripts that need to ensure a directory structure without failing on re-runs.
Installation
The mkdir command ships as part of GNU coreutils on virtually every Linux distribution. Verify its presence with:
mkdir --version
If mkdir is somehow missing (extremely rare, usually only in minimal containers), install the coreutils package:
Ubuntu and Debian-based distributions:
sudo apt install coreutils
Fedora, RHEL, Rocky Linux, and AlmaLinux:
sudo dnf install coreutils
Arch Linux and Manjaro:
sudo pacman -S coreutils
openSUSE:
sudo zypper install coreutils
Alpine Linux:
sudo apk add coreutils
Gentoo:
sudo emerge sys-apps/coreutils
Void Linux:
sudo xbps-install -S coreutils
Practical Examples
Example 1: Create a Single Directory
The most common use case is creating a single directory in your current location:
mkdir new_directory
This creates new_directory in your current working directory. With the common 022 umask (the user file-creation mask that removes write access for group and others, similar to Windows inheriting read-only permissions for other accounts) the permissions resolve to 755 (owner can read/write/execute, group and others can read/execute); a different umask produces different defaults. The directory appears immediately; no confirmation message appears unless you add the -v flag.
Example 2: Create Multiple Directories at Once
When setting up project structures, you often need several directories created simultaneously:
mkdir docs src tests config
This creates four separate directories (docs, src, tests, and config) in the current location with a single command. Each directory is independent; if one already exists, mkdir will error on that specific name but still create the others.
Example 3: Create Nested Directory Structures
The -p option creates parent directories automatically, letting you build entire directory trees in one command:
mkdir -p project/src/components/auth
This creates the entire path. If project, src, components, or auth directories don’t exist, mkdir creates them all in sequence. Without -p, you’d get an error if any parent directory is missing. This option is essential for scripts that need to ensure directory structures exist without failing on re-runs.
Example 4: Set Permissions During Creation
The -m option lets you specify permissions at creation time, which is more secure than creating a directory with default permissions and then changing them with chmod:
mkdir -m 700 private_data
This creates private_data with permissions set to 700 (read, write, and execute for the owner only; no access for group or others). Using octal notation like 700 or 755 is the most common approach, though you can also use symbolic notation: mkdir -m u=rwx,g=,o= private_data achieves the same result.
Example 5: Use Verbose Output for Confirmation
When creating many directories or running mkdir in scripts, the -v flag provides confirmation of what was created:
mkdir -v reports logs backups
This prints messages like “mkdir: created directory ‘reports'” for each directory. Combine -v with -p to see the entire path creation: mkdir -pv data/2024/november shows each intermediate directory as it’s created.
Example 6: Handle Directory Names with Spaces
When directory names contain spaces, enclose them in quotes to prevent the shell from treating each word as a separate directory name:
mkdir "Client Projects" "Meeting Notes"
This creates two directories with spaces in their names. You can also escape individual spaces with backslashes (mkdir Client\ Projects), but quotes are clearer when directory names contain multiple spaces.
Example 7: Create Directories with Full Paths
Specify absolute or relative paths to create directories anywhere in the filesystem, not just your current location:
sudo mkdir /var/www/mysite/uploads
mkdir ~/documents/2024/invoices
The first command creates uploads in /var/www/mysite (the parent directories must already exist unless you add -p) and requires sudo because /var is a system directory. The second creates invoices in your home directory under documents/2024. Using full paths is helpful when working from different directories or when scripting directory creation for system-wide locations.
Example 8: Create Hidden Directories
In Linux, files and directories starting with a dot (.) are hidden from normal directory listings:
mkdir .cache .config .local
This creates three hidden directories. They won’t appear in ls output unless you use ls -a (show all files). Hidden directories are commonly used for application configuration, cache data, and user-specific settings that shouldn’t clutter normal directory listings.
Example 9: Use Brace Expansion for Sequential Directories
Bash’s brace expansion feature lets you generate sequences of directory names efficiently:
mkdir week{1..12}
mkdir -p project/{src,tests,docs,config}
The first command creates week1, week2, through week12. The second creates four directories under project in one command. You can combine ranges and lists: mkdir -p 2024/{q1,q2,q3,q4}/{reports,data} creates a two-level structure with quarters and subdirectories for each quarter.
Example 10: Prevent Errors When Directories Exist
The -p option silently succeeds even when directories already exist, making it perfect for idempotent scripts that can run repeatedly without errors:
mkdir -p logs backups data
Run this multiple times and it completes successfully each time. If the directories exist, nothing changes; if they’re missing, they’re created. Without -p, running mkdir logs when logs already exists produces an error and fails.
Example 11: Create Directories from a Text File
When you have a list of directories to create (perhaps from a project template or inventory), read the file with a simple loop so each name stays intact:
while IFS= read -r dir; do
mkdir -- "$dir"
done < directory_list.txt
If directory_list.txt contains directory names (one per line), this loop creates all of them while preserving spaces and special characters. Add -p to the mkdir invocation (mkdir -p -- "$dir") when the list includes nested paths so parent directories are created automatically. This pattern is useful when provisioning consistent directory structures across multiple systems.
Example 12: Combine Options for Complex Directory Creation
Real-world scenarios often require combining multiple mkdir options:
sudo mkdir -pvm 750 /var/app/data/{uploads,exports,cache}
This creates three directories under /var/app/data (creating /var/app/data if needed), sets permissions to 750 (owner full access, group read/execute, others none), and prints verbose output showing each directory created. Combining -p, -v, and -m gives you safe nested creation with custom permissions and confirmation feedback, while sudo provides the root permissions required in /var.
Example 13: Set Sticky Bit for Shared Directories
The sticky bit (octal 1000) protects files in shared directories so only the file owner (or root) can delete or rename their own files:
mkdir -m 1777 /tmp/shared_workspace
This creates a directory with full permissions for everyone (777) plus the sticky bit (1), resulting in octal 1777. The sticky bit is essential for directories like /tmp where multiple users need write access but shouldn’t be able to delete each other’s files. You’ll see a t in the permissions when running ls -ld.
Example 14: Set SGID Bit for Group Collaboration
The SGID (Set Group ID) bit ensures files created within a directory inherit the directory’s group ownership rather than the creating user’s primary group, which is valuable for team collaboration:
sudo mkdir -m 2775 /opt/team_project
This creates a directory with read/write/execute for owner and group, read/execute for others (775), plus the SGID bit (2), resulting in octal 2775. When team members create files in this directory, those files automatically belong to the directory’s group instead of their personal group. You’ll see an s in the group execute position when running ls -ld. The SUID bit (4) is rarely used with directories and generally reserved for executable files requiring elevated privileges, and sudo is necessary here because /opt is system-owned.
Example 15: Integrate mkdir with find for Bulk Operations
When you need to recreate directory structures or mirror hierarchies, combine find with mkdir to automate complex operations:
find source_project -type d -exec sh -c 'rel=${1#source_project}; mkdir -p "backup_project$rel"' _ {} \;
This finds all directories under source_project and recreates the structure directly under backup_project. The shell snippet strips the source_project/ prefix, creates backup_project once when the root entry is processed, then appends each relative path for nested directories. This pattern is useful when preparing staging environments, creating backup directory trees before file syncs, or provisioning parallel test structures. For simpler mirroring without files, run:
rsync -av --include='*/' --exclude='*' source/ destination/
The rsync command copies only directories while skipping files, producing a clean skeleton of the original project.
Common Mistakes and Troubleshooting
Permission Denied Errors
When mkdir fails with “Permission denied,” you lack write permission in the parent directory. Check permissions with ls -ld /path/to/parent and either request appropriate access or use a location where you have write permissions. System directories like /usr, /opt, or /var typically require sudo:
sudo mkdir /var/app/logs
File Exists Errors
The error “cannot create directory: File exists” means a file or directory with that name already exists. If you want to proceed regardless, add -p to make the command idempotent. If a regular file (not a directory) blocks the path, you must remove or rename it before creating the directory.
Missing Parent Directory Errors
Without -p, mkdir fails if parent directories don’t exist: “cannot create directory: No such file or directory.” Always use mkdir -p path/to/nested/dir for nested structures or when you’re unsure whether parents exist.
Special Characters in Directory Names
Avoid special characters like / \ : * ? " < > | in directory names. The forward slash is a path separator and cannot appear in names. Other characters cause shell interpretation issues. When names contain spaces, apostrophes, or quotes, always enclose the entire name in double quotes or escape special characters with backslashes.
Incorrect Permission Syntax
When using -m, ensure octal values are valid (0-7 for each digit). Common mistakes include using 8 or 9 (invalid octal digits) or forgetting that permissions require three or four digits. If symbolic notation seems clearer, use -m u=rwx,g=rx,o= syntax instead of octal.
Filesystem Limitations
Some filesystems impose path length limits (typically 4096 characters on modern Linux) or directory depth restrictions. Extremely deep nesting can cause failures. Additionally, filesystems have inode limits; if you’ve exhausted available inodes, mkdir will fail even with free disk space. Check with df -i to see inode usage.
Conclusion
The mkdir command provides complete control over directory creation, handling everything from single folders to complex nested structures with precise permissions. By mastering core options like -p for automatic parent creation, -m for setting permissions at creation time, and -v for confirmation feedback, you can structure filesystems efficiently and build reliable scripts that provision directory trees without manual intervention. Whether you’re organizing project files, configuring server environments, or automating deployment workflows, mkdir gives you the building blocks to create exactly the directory structure you need. When you need to remove empty directories, the rmdir command provides the complementary functionality for clean filesystem management.