google-site-verification: google61fe8ba583a51912.html
Complete Guide to Bash mkdir Command

Introduction to mkdir

The mkdir (make directory) command is a fundamental utility in Unix/Linux systems for creating directories (folders). It allows users to create single directories, nested directory structures, and set permissions at creation time. Understanding mkdir thoroughly is essential for file system organization, script writing, and system administration.

Key Concepts

  • Directory Creation: Creating new folders in the filesystem
  • Parent Directories: Creating intermediate directories automatically
  • Permissions: Setting access rights at creation time
  • Hierarchical Structure: Building nested directory trees
  • Error Handling: Dealing with existing directories and permissions

1. Basic Usage

Creating a Single Directory

#!/bin/bash # Create a single directory in current location mkdir projects mkdir documents mkdir downloads # Create directory with absolute path mkdir /home/user/new_folder mkdir ~/backups mkdir /tmp/work_files # Create directory with spaces (use quotes or escape) mkdir "My Documents" mkdir My\ Documents mkdir 'Project Files' # Create multiple directories at once mkdir dir1 dir2 dir3 mkdir projects downloads documents # Create directory and verify mkdir test_dir && ls -ld test_dir # Create directory in parent location mkdir ../shared mkdir ../../global

Creating with Different Paths

#!/bin/bash # Create in current directory mkdir ./local_folder # Create in parent directory mkdir ../sibling_folder # Create in home directory mkdir ~/new_folder # Create in root (requires sudo usually) sudo mkdir /opt/myapp # Create relative to current mkdir ../../project/src # Create using variables BASE_DIR="/opt/app" mkdir "$BASE_DIR" mkdir "${BASE_DIR}/logs" mkdir "${BASE_DIR}/config" # Create with timestamp mkdir "backup_$(date +%Y%m%d)" mkdir "logs_$(date +%Y-%m-%d_%H-%M-%S)"

2. Essential Options

Common Options Reference

#!/bin/bash # -p: Create parent directories as needed mkdir -p parent/child/grandchild # -v: Verbose output (show what's being created) mkdir -v new_folder mkdir -v -p a/b/c # -m: Set permissions (mode) at creation mkdir -m 755 public_dir mkdir -m 700 private_dir mkdir -m 777 shared_dir # Combine options mkdir -pv projects/src/main mkdir -pm 755 apps/web/static # -p with existing directories (no error) mkdir -p existing_folder # No error if exists mkdir existing_folder # Error if exists # Examples mkdir -v backup # Create with message mkdir -p a/b/c/d/e/f # Create nested directories mkdir -m 700 ~/private # Private directory mkdir -pv /tmp/test/{sub1,sub2} # Create multiple subdirs

Practical Option Combinations

#!/bin/bash # Create full path with permissions create_path() { local path="$1" local mode="${2:-755}" mkdir -p -m "$mode" "$path" echo "Created: $path with mode $mode" } # Create project structure create_project() { local name="$1" mkdir -pv "$name"/{src,bin,docs,tests} mkdir -pv "$name"/src/{main,test} mkdir -pv "$name"/docs/{api,user} echo "Project structure created for: $name" } # Safe directory creation safe_mkdir() { local dir="$1" if [ -e "$dir" ]; then echo "Error: $dir already exists" >&2 return 1 fi mkdir "$dir" } # Create with timestamp and permissions create_backup_dir() { local base="${1:-./backups}" local mode="${2:-750}" local date=$(date +%Y%m%d_%H%M%S) local dir="$base/$date" mkdir -p -m "$mode" "$dir" echo "$dir" } # Usage create_path "/opt/myapp/data" 750 create_project "myapp" safe_mkdir "unique_dir" backup_dir=$(create_backup_dir "/backups" 700)

3. Creating Nested Directories

Using -p for Parent Directories

#!/bin/bash # Basic nested creation mkdir -p parent/child/grandchild # Multiple levels mkdir -p a/b/c/d/e/f/g # Create with complex paths mkdir -p /opt/app/{config,logs,data} mkdir -p project/src/{main,test}/java mkdir -p ~/work/{2024/{q1,q2,q3,q4},archive} # Create from variable BASE="/opt/myapp" mkdir -p "$BASE"/{bin,conf,logs,data/{db,cache}} # Create with brace expansion mkdir -p src/{main,test}/{java,resources} mkdir -p project/{lib,bin,doc}/{html,pdf} # Nested with permissions mkdir -pm 755 app/{web/{static,templates},api} # Create and cd into directory mkcd() { mkdir -p "$1" && cd "$1" } # Usage mkcd /tmp/test/nested/dir

Complex Directory Structures

#!/bin/bash # Create project skeleton create_java_project() { local name="$1" mkdir -p "$name"/src/{main,test}/{java,resources} mkdir -p "$name"/src/main/java/com/example mkdir -p "$name"/src/test/java/com/example mkdir -p "$name"/{target,lib,docs} echo "Java project structure created for: $name" } # Create web application structure create_webapp() { local name="$1" mkdir -p "$name"/{public,src,dist} mkdir -p "$name"/public/{css,js,images} mkdir -p "$name"/src/{components,utils,styles} mkdir -p "$name"/src/components/{common,features} echo "Web app structure created for: $name" } # Create data science project create_ds_project() { local name="$1" mkdir -p "$name"/{data/{raw,processed,external},notebooks,src,models,outputs} mkdir -p "$name"/src/{data,features,models,visualization} mkdir -p "$name"/configs echo "Data science project created for: $name" } # Create multi-module project create_multi_module() { local root="$1" shift local modules=("$@") mkdir -p "$root"/{shared,common} for module in "${modules[@]}"; do mkdir -p "$root/$module"/{src,test,resources} done } # Usage create_java_project "myapp" create_webapp "frontend" create_ds_project "analysis" create_multi_module "project" "core" "web" "api"

4. Setting Permissions at Creation

Using -m Option

#!/bin/bash # Basic permission settings mkdir -m 755 public # rwxr-xr-x mkdir -m 700 private # rwx------ mkdir -m 777 shared # rwxrwxrwx mkdir -m 644 readonly # rw-r--r-- (unusual for dirs) # Octal permissions mkdir -m 755 dir1 mkdir -m 750 dir2 mkdir -m 770 dir3 mkdir -m 700 dir4 mkdir -m 555 dir5 # Read-only directory # Symbolic permissions mkdir -m u=rwx,g=rx,o=rx dir6 mkdir -m u=rwx,g=,o= dir7 # Private mkdir -m a=rwx dir8 # All permissions mkdir -m u=rwx,g=rwxs,o= dir9 # With setgid # Combining with -p mkdir -pm 755 a/b/c/d mkdir -pm 700 ~/private/{docs,config} # Check permissions ls -ld dir1 dir2 dir3 # Create with umask consideration (umask 022 && mkdir dir10) # Creates with 755 (umask 077 && mkdir dir11) # Creates with 700

Advanced Permission Patterns

#!/bin/bash # Create shared directory with sticky bit mkdir -m 1777 shared # /tmp style directory # Create with setgid (new files inherit group) mkdir -m 2755 project_group # Setgid + rwxr-xr-x # Create with setuid (rare for directories) mkdir -m 4755 special_dir # Create restricted directory for web server mkdir -m 755 public_html mkdir -m 700 private_data # Create directories for different purposes create_secure_dir() { local dir="$1" mkdir -m 700 "$dir" } create_shared_dir() { local dir="$1" mkdir -m 775 "$dir" chown :www-data "$dir" 2>/dev/null || true } create_temp_dir() { local dir="$1" mkdir -m 1777 "$dir" } # Create with specific user/group create_owned_dir() { local dir="$1" local user="$2" local group="$3" local mode="${4:-755}" mkdir -m "$mode" "$dir" chown "$user:$group" "$dir" } # Usage create_secure_dir "secrets" create_shared_dir "uploads" create_temp_dir "/tmp/custom" create_owned_dir "/opt/app" "www-data" "www-data" 750

5. Error Handling

Common Error Scenarios

#!/bin/bash # Error: Directory already exists mkdir existing_dir mkdir: cannot create directory ‘existing_dir’: File exists # Solution: Use -p to suppress error mkdir -p existing_dir # Error: No such file or directory (parent missing) mkdir parent/child mkdir: cannot create directory ‘parent/child’: No such file or directory # Solution: Use -p to create parents mkdir -p parent/child # Error: Permission denied mkdir /root/test mkdir: cannot create directory ‘/root/test’: Permission denied # Solution: Use sudo sudo mkdir /root/test # Error: Read-only filesystem mkdir /media/cdrom/test mkdir: cannot create directory ‘/media/cdrom/test’: Read-only file system # Solution: Can't create on read-only filesystem # Error: Invalid characters mkdir "invalid/" mkdir: cannot create directory ‘invalid/’: Invalid argument # Solution: Remove invalid characters mkdir "valid"

Robust Error Handling

#!/bin/bash # Safe directory creation with error checking safe_mkdir() { local dir="$1" local mode="${2:-}" # Check if path already exists if [ -e "$dir" ]; then if [ -d "$dir" ]; then echo "Warning: $dir already exists and is a directory" >&2 return 0 else echo "Error: $dir exists but is not a directory" >&2 return 1 fi fi # Create directory with optional mode if [ -n "$mode" ]; then mkdir -m "$mode" "$dir" 2>/dev/null else mkdir "$dir" 2>/dev/null fi local result=$? if [ $result -eq 0 ]; then echo "Created: $dir" else echo "Error: Failed to create $dir" >&2 fi return $result } # Create with retry logic mkdir_with_retry() { local dir="$1" local max_attempts="${2:-3}" local attempt=1 while [ $attempt -le $max_attempts ]; do if mkdir "$dir" 2>/dev/null; then echo "Created $dir on attempt $attempt" return 0 fi echo "Attempt $attempt failed, retrying..." >&2 sleep $((attempt * 2)) attempt=$((attempt + 1)) done echo "Failed to create $dir after $max_attempts attempts" >&2 return 1 } # Create with parent verification mkdir_verify() { local path="$1" local required_parents="${2:-}" # Check parent directory exists if required if [ -n "$required_parents" ]; then local parent=$(dirname "$path") if [ ! -d "$parent" ]; then echo "Error: Parent directory $parent does not exist" >&2 return 1 fi fi mkdir -p "$path" } # Create with logging log_mkdir() { local dir="$1" local log_file="${2:-/var/log/mkdir.log}" if mkdir -p "$dir" 2>>"$log_file"; then echo "$(date): Created $dir" >> "$log_file" return 0 else echo "$(date): Failed to create $dir" >> "$log_file" return 1 fi } # Usage safe_mkdir "/tmp/test" 755 mkdir_with_retry "/tmp/unique_dir" 5 mkdir_verify "/opt/app/data" "required" log_mkdir "/var/log/myapp" "/var/log/myapp_mkdir.log"

6. Advanced Directory Creation

Using Brace Expansion

#!/bin/bash # Basic brace expansion mkdir {dir1,dir2,dir3} mkdir {a,b,c}/{x,y,z} mkdir project/{src,test,docs} mkdir -p data/{2024/{01,02,03},archive} # Nested brace expansion mkdir -p src/{main,test}/{java,resources}/{com/example} mkdir -p {prod,dev,test}/{config,logs,data} mkdir -p project/{lib,bin,share}/{linux,windows,macos} # Combining with ranges mkdir {1..5} # Creates 1,2,3,4,5 mkdir {a..e} # Creates a,b,c,d,e mkdir {01..12} # Zero-padded numbers mkdir q{1..4} # q1,q2,q3,q4 # More complex combinations mkdir -p 2024/{Q{1..4}/{month{1..3}}} mkdir -p {backend,frontend}/src/{components,utils,pages} mkdir -p data/{raw,processed}/{train,test,validate}/{images,labels} # Practical example: Create test data structure create_test_data() { mkdir -p test_data/{batch{1..5}/{positive,negative,neutral}} mkdir -p test_data/{validation,training,testing}/{set{1..3}} } # Create multiple projects create_projects() { local projects=("web" "api" "worker" "scheduler") local environments=("dev" "staging" "prod") for project in "${projects[@]}"; do for env in "${environments[@]}"; do mkdir -p "$project/$env"/{config,logs,data} done done }

Programmatic Directory Creation

#!/bin/bash # Create directories from array dirs=( "project/src/main" "project/src/test" "project/docs/api" "project/docs/user" "project/config/dev" "project/config/prod" ) for dir in "${dirs[@]}"; do mkdir -p "$dir" done # Create from file list while IFS= read -r dir; do mkdir -p "$dir" done < directories.txt # Create with counter for i in {1..10}; do mkdir -p "batch_$i"/{input,output,logs} done # Create based on date for month in {01..12}; do mkdir -p "logs/2024/$month"/{01..31} done # Create with conditions for i in {1..100}; do if [ $((i % 2)) -eq 0 ]; then mkdir "even_dir_$i" else mkdir "odd_dir_$i" fi done # Create based on file content create_from_config() { local config="$1" while IFS=':' read -r name mode; do mkdir -m "$mode" "$name" done < "$config" } # Usage example config.txt: # public:755 # private:700 # shared:775

7. Script Examples

Directory Creation Functions

#!/bin/bash # Comprehensive directory creation library # Create directory if not exists ensure_dir() { local dir="$1" local mode="${2:-755}" if [ ! -d "$dir" ]; then mkdir -p -m "$mode" "$dir" echo "Created directory: $dir" else echo "Directory already exists: $dir" fi } # Create temporary directory make_temp_dir() { local prefix="${1:-tmp}" local dir dir=$(mktemp -d "/tmp/${prefix}.XXXXXX") echo "$dir" } # Create timestamped directory make_timestamp_dir() { local base="${1:-.}" local name="${2:-backup}" local timestamp=$(date +%Y%m%d_%H%M%S) local dir="$base/${name}_$timestamp" mkdir -p "$dir" echo "$dir" } # Create directory with all subdirectories make_full_path() { local path="$1" local mode="${2:-755}" IFS='/' read -ra parts <<< "$path" local current="" for part in "${parts[@]}"; do if [ -n "$part" ]; then current="$current/$part" if [ ! -d "$current" ]; then mkdir -m "$mode" "$current" echo "Created: $current" fi fi done } # Create versioned directories make_versioned_dirs() { local base="$1" local versions=("v1.0" "v1.1" "v2.0" "v2.1") for version in "${versions[@]}"; do mkdir -p "$base/$version"/{bin,lib,conf} done } # Create directory tree with metadata make_tree_with_metadata() { local root="$1" local metadata_file="$root/.metadata" mkdir -p "$root" echo "Created: $(date)" > "$metadata_file" echo "User: $USER" >> "$metadata_file" # Create subdirectories mkdir -p "$root"/{data,logs,temp} # Add metadata to subdirs for dir in data logs temp; do echo "Parent: $root" > "$root/$dir/.metadata" done }

Installation Script Example

#!/bin/bash # Application installation script with directory creation APP_NAME="myapp" INSTALL_DIR="/opt/$APP_NAME" CONFIG_DIR="/etc/$APP_NAME" LOG_DIR="/var/log/$APP_NAME" DATA_DIR="/var/lib/$APP_NAME" RUN_DIR="/var/run/$APP_NAME" # Colors for output RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' NC='\033[0m' # No Color log() { echo -e "${GREEN}[INFO]${NC} $1" } warn() { echo -e "${YELLOW}[WARN]${NC} $1" } error() { echo -e "${RED}[ERROR]${NC} $1" exit 1 } create_directories() { log "Creating application directories..." # Main application directory ensure_dir "$INSTALL_DIR" 755 ensure_dir "$INSTALL_DIR/bin" 755 ensure_dir "$INSTALL_DIR/lib" 755 ensure_dir "$INSTALL_DIR/plugins" 755 # Configuration directory ensure_dir "$CONFIG_DIR" 750 ensure_dir "$CONFIG_DIR/default" 755 ensure_dir "$CONFIG_DIR/custom" 750 # Log directory ensure_dir "$LOG_DIR" 750 ensure_dir "$LOG_DIR/archive" 750 # Data directory ensure_dir "$DATA_DIR" 750 ensure_dir "$DATA_DIR/db" 750 ensure_dir "$DATA_DIR/cache" 750 ensure_dir "$DATA_DIR/temp" 750 # Run directory (for PID files) ensure_dir "$RUN_DIR" 755 log "Directory structure created successfully" } ensure_dir() { local dir="$1" local mode="$2" if [ ! -d "$dir" ]; then mkdir -p -m "$mode" "$dir" || error "Failed to create $dir" log " Created: $dir ($mode)" else warn " Directory already exists: $dir" fi } set_permissions() { log "Setting directory permissions..." chown -R root:root "$INSTALL_DIR" chown -R root:adm "$CONFIG_DIR" chown -R root:adm "$LOG_DIR" chown -R $APP_USER:$APP_GROUP "$DATA_DIR" 2>/dev/null || warn "User $APP_USER not found" log "Permissions set successfully" } check_prerequisites() { # Check if running as root if [ "$EUID" -ne 0 ]; then error "This script must be run as root" fi # Check available disk space local required_space=1000000 # 1GB in KB local available_space=$(df "$INSTALL_DIR" | awk 'NR==2 {print $4}') if [ "$available_space" -lt "$required_space" ]; then error "Insufficient disk space. Need at least 1GB" fi } main() { log "Starting installation of $APP_NAME..." check_prerequisites create_directories set_permissions log "Installation completed successfully" } # Run main function main

8. Integration with Other Commands

Using with find

#!/bin/bash # Create directories for each file type find . -type f -name "*.txt" | while read file; do dir=$(dirname "$file")/txt_backup mkdir -p "$dir" cp "$file" "$dir/" done # Create directory structure matching another find source_dir -type d | while read dir; do target="dest_dir/${dir#source_dir/}" mkdir -p "$target" done # Create directories for each extension find . -type f | sed -n 's/.*\.//p' | sort -u | while read ext; do mkdir -p "by_extension/$ext" done # Create directories based on file dates find . -type f -printf '%TY-%Tm\n' | sort -u | while read date; do mkdir -p "by_date/$date" done

Using with xargs

#!/bin/bash # Create directories from list echo "dir1 dir2 dir3" | xargs mkdir # Create from file cat directories.txt | xargs mkdir -p # Parallel directory creation seq 1 100 | xargs -P 10 -I {} mkdir "dir_{}" # Create with options find . -name "*.tmp" | sed 's/\.tmp$//' | xargs -I {} mkdir -p "{}_backup" # Safe xargs with null delimiter find . -type d -print0 | xargs -0 -I {} mkdir "copy_{}"

Using with rsync

#!/bin/bash # Create destination directory structure rsync -av --files-from=<(find source -type f) source/ dest/ # Sync directory structure only rsync -av -f"+ */" -f"- *" source/ dest/ # Create directories before rsync ssh user@host "mkdir -p /remote/path/subdirs" # Rsync with directory creation rsync -av --rsync-path="mkdir -p /dest && rsync" source/ user@host:/dest/

9. Special Use Cases

Creating Directories with Special Characters

#!/bin/bash # Spaces mkdir "My Documents" mkdir My\ Documents mkdir 'Project Files 2024' # Special characters mkdir "project#123" mkdir "file&name" mkdir "[email protected]" mkdir "path+plus" # Unicode/UTF-8 mkdir "数据备份" mkdir "проекты" mkdir "📁documents" # Starting with dash (use -- to stop option parsing) mkdir -- -directory mkdir -- --double-dash # With colons mkdir "name:with:colons" # With brackets mkdir "project[2024]" mkdir "file{version}" # Safe handling in scripts name="My Document" mkdir "$name" mkdir "${name// /_}" # Replace spaces with underscores

Creating Temporary Directories

#!/bin/bash # Using mktemp temp_dir=$(mktemp -d) echo "Temporary directory: $temp_dir" # Use directory # Clean up rm -rf "$temp_dir" # Custom prefix temp_dir=$(mktemp -d /tmp/myapp.XXXXXX) temp_dir=$(mktemp -d --tmpdir=/var/tmp myapp.XXXX) # Trap cleanup cleanup() { if [ -n "$temp_dir" ] && [ -d "$temp_dir" ]; then rm -rf "$temp_dir" echo "Cleaned up $temp_dir" fi } trap cleanup EXIT temp_dir=$(mktemp -d) cd "$temp_dir" || exit 1 # Work in temp directory mkdir {input,output,logs} echo "Working in $temp_dir" # Script will automatically clean up on exit # Multiple temp directories build_dir=$(mktemp -d) cache_dir=$(mktemp -d) # Create with specific permissions secure_temp() { local dir dir=$(mktemp -d) chmod 700 "$dir" echo "$dir" }

Creating Directories for Mount Points

#!/bin/bash # Create mount point sudo mkdir -p /mnt/backup sudo mount /dev/sdb1 /mnt/backup # Create multiple mount points for i in {1..5}; do sudo mkdir -p "/mnt/disk$i" done # Create with specific permissions for mount create_mount_point() { local point="$1" local user="${2:-$USER}" sudo mkdir -p "$point" sudo chown "$user" "$point" sudo chmod 755 "$point" } # Create loop device mount point create_loop_mount() { local image="$1" local point="/mnt/loop_$(basename "$image")" mkdir -p "$point" sudo mount -o loop "$image" "$point" echo "Mounted $image at $point" } # Usage create_mount_point "/media/extradrive" "$USER"

10. Performance Considerations

Bulk Directory Creation

#!/bin/bash # Efficient bulk creation time { for i in {1..1000}; do mkdir "dir_$i" done } # Using xargs (faster for many directories) time { seq 1 1000 | xargs -P 4 -I {} mkdir "dir_{}" } # Using parallel (if installed) time { seq 1 1000 | parallel mkdir "dir_{}" } # Create directory tree efficiently create_tree() { local depth="${1:-3}" local breadth="${2:-5}" # Use brace expansion for efficient creation local dirs="" for i in $(seq 1 $depth); do dirs="$dirs/level$i" done mkdir -p "root$dirs" # Create multiple leaf directories for i in $(seq 1 $breadth); do mkdir -p "root$dirs/branch$i" done } # Benchmark different methods benchmark_mkdir() { local count=1000 echo "Method 1: Sequential" time { for i in $(seq 1 $count); do mkdir "test1_$i" 2>/dev/null done rm -rf test1_* } echo "Method 2: xargs" time { seq 1 $count | xargs -I {} mkdir "test2_{}" 2>/dev/null rm -rf test2_* } echo "Method 3: Brace expansion" time { eval mkdir test3_{1..$count} 2>/dev/null rm -rf test3_* } }

Filesystem Considerations

#!/bin/bash # Check filesystem type before creating check_fs_type() { local dir="$1" local fs_type=$(df -T "$dir" | awk 'NR==2 {print $2}') echo "Filesystem type: $fs_type" } # Create with consideration for filesystem limits safe_mkdir_with_limits() { local path="$1" local max_path=$(getconf PATH_MAX /) local max_name=$(getconf NAME_MAX /) # Check path length if [ ${#path} -gt $max_path ]; then echo "Error: Path too long (max $max_path)" >&2 return 1 fi # Check component names IFS='/' read -ra parts <<< "$path" for part in "${parts[@]}"; do if [ ${#part} -gt $max_name ]; then echo "Error: Component '$part' too long (max $max_name)" >&2 return 1 fi done mkdir -p "$path" } # Create directories on specific filesystem create_on_fs() { local base="$1" local fs="$2" shift 2 # Check if base is on correct filesystem local base_fs=$(df -T "$base" | awk 'NR==2 {print $2}') if [ "$base_fs" != "$fs" ]; then echo "Error: $base is on $base_fs, not $fs" >&2 return 1 fi for dir in "$@"; do mkdir -p "$base/$dir" done }

11. Best Practices and Tips

Shell Configuration

# ~/.bashrc additions # Aliases for common mkdir operations alias mkdir='mkdir -p' # Always create parents alias mkv='mkdir -v' # Verbose alias mkdir='mkdir -v' # Verbose by default alias mkd='mkdir -p' # Create with parents alias mk='mkdir -p' # Short version # Function to create and cd mkcd() { mkdir -p "$1" && cd "$1" } # Function to create multiple directories mkd() { for dir in "$@"; do mkdir -p "$dir" done } # Function to create with timestamp mkt() { local base="${1:-.}" local name="${2:-dir}" local timestamp=$(date +%Y%m%d_%H%M%S) mkdir -p "$base/${name}_$timestamp" } # Function to create with permissions mkdm() { local mode="$1" local dir="$2" mkdir -m "$mode" -p "$dir" } # Function to create project structure mkproj() { local name="$1" mkdir -p "$name"/{src,bin,docs,test} mkdir -p "$name"/src/{main,test} echo "Project $name created" } # Tab completion for mkcd _mkcd_complete() { COMPREPLY=($(compgen -d -- "${COMP_WORDS[COMP_CWORD]}")) } complete -F _mkcd_complete mkcd

Security Best Practices

#!/bin/bash # 1. Always check before creating in sensitive locations safe_mkdir_sensitive() { local dir="$1" # Don't create in root if [ "$dir" = "/" ] || [ "$dir" = "/etc" ] || [ "$dir" = "/bin" ]; then echo "Error: Refusing to create directory in system location" >&2 return 1 fi mkdir -p "$dir" } # 2. Set secure permissions by default umask 077 mkdir private_dir # 3. Avoid race conditions (CWE-367) if mkdir "$dir" 2>/dev/null; then echo "Successfully created $dir" else echo "Directory $dir already exists or cannot be created" fi # 4. Check symlinks before creating safe_mkdir_no_symlink() { local dir="$1" if [ -L "$dir" ]; then echo "Error: $dir is a symlink" >&2 return 1 fi mkdir -p "$dir" } # 5. Create with least privileges drop_privileges() { local user="${1:-nobody}" local dir="$2" if id "$user" >/dev/null 2>&1; then sudo -u "$user" mkdir -p "$dir" else echo "User $user does not exist" >&2 return 1 fi } # 6. Validate directory names validate_dirname() { local name="$1" # Check for invalid characters if [[ "$name" =~ [/] ]]; then echo "Error: Directory name contains slash" >&2 return 1 fi # Check length if [ ${#name} -gt 255 ]; then echo "Error: Directory name too long" >&2 return 1 fi return 0 } # 7. Create with audit logging audit_mkdir() { local dir="$1" local user="$USER" local pid=$$ if mkdir -p "$dir"; then logger -p user.info "mkdir: $user($pid) created $dir" else logger -p user.err "mkdir: $user($pid) failed to create $dir" fi }

Tips for Scripts

#!/bin/bash # 1. Always use -p in scripts mkdir -p /var/log/myapp # 2. Check return codes if ! mkdir -p "$dir"; then echo "Failed to create $dir" >&2 exit 1 fi # 3. Use variables for paths LOG_DIR="/var/log/myapp" mkdir -p "$LOG_DIR" # 4. Create with proper permissions mkdir -m 755 -p "$LOG_DIR" # 5. Handle existing directories gracefully mkdir -p "$dir" 2>/dev/null || true # 6. Use trap for temporary directories cleanup() { rm -rf "$TMPDIR" } TMPDIR=$(mktemp -d) trap cleanup EXIT # 7. Create directory structure from config while IFS=: read dir mode owner group; do mkdir -p "$dir" chmod "$mode" "$dir" chown "$owner:$group" "$dir" 2>/dev/null done < directories.cfg # 8. Test before creating if [ -w "$(dirname "$dir")" ]; then mkdir -p "$dir" else echo "Parent directory not writable" >&2 exit 1 fi # 9. Create multiple directories atomically create_atomic() { local dirs=("$@") for dir in "${dirs[@]}"; do if ! mkdir -p "$dir"; then # Rollback for d in "${dirs[@]}"; do [ -d "$d" ] && rmdir "$d" 2>/dev/null done return 1 fi done return 0 } # 10. Use readlink to resolve paths abs_dir=$(readlink -f "$rel_dir") mkdir -p "$abs_dir"

12. Troubleshooting

Common Issues and Solutions

#!/bin/bash # Issue: Permission denied # Solution: Check permissions and use sudo if needed ls -ld "$(dirname "$dir")" sudo mkdir -p "$dir" # Issue: No space left on device # Solution: Check disk space df -h "$dir" du -sh "$dir" 2>/dev/null # Issue: Read-only filesystem # Solution: Check mount options mount | grep "$(df "$dir" | awk 'NR==2 {print $1}')" # Issue: Invalid argument (bad characters) # Solution: Sanitize filename sanitize_name() { echo "$1" | tr -cd '[:alnum:] ._-' } mkdir "$(sanitize_name "$raw_name")" # Issue: File exists but not a directory # Solution: Remove or rename file if [ -e "$dir" ] && [ ! -d "$dir" ]; then mv "$dir" "$dir.bak" mkdir "$dir" fi # Issue: Path too long # Solution: Use shorter names or reorganize max_path=$(getconf PATH_MAX "$dir") echo "Max path length: $max_path" # Issue: Permission denied in script but works manually # Solution: Check environment and umask echo "umask: $(umask)" echo "PATH: $PATH" echo "User: $(whoami)" # Diagnostic function diagnose_mkdir() { local dir="$1" echo "=== Diagnosing mkdir for: $dir ===" echo "Current user: $(whoami)" echo "Current directory: $(pwd)" echo "Parent directory: $(dirname "$dir")" if [ -e "$(dirname "$dir")" ]; then ls -ld "$(dirname "$dir")" df -h "$(dirname "$dir")" else echo "Parent directory does not exist" fi if [ -e "$dir" ]; then echo "Target already exists:" ls -ld "$dir" fi echo "Filesystem type: $(df -T "$(dirname "$dir")" 2>/dev/null | awk 'NR==2 {print $2}')" echo "Free space: $(df -h "$(dirname "$dir")" 2>/dev/null | awk 'NR==2 {print $4}')" }

Debugging Techniques

#!/bin/bash # Enable debug mode set -x mkdir -p test/dir set +x # Verbose output mkdir -v parent/child # Dry run (simulate) mkdir -pv --dry-run a/b/c # Trace system calls strace -e trace=file mkdir testdir 2>&1 | grep mkdir # Check with shellcheck # shellcheck disable=SC2164 cd "$(mktemp -d)" || exit 1 # Log all mkdir operations mkdir() { echo "$(date): mkdir $*" >> /tmp/mkdir.log command mkdir "$@" } # Debug with bash debugger trap 'echo "About to create: $BASH_COMMAND"' DEBUG mkdir test trap - DEBUG # Profile directory creation time mkdir -p a/b/c/d/e/f # Check filesystem limits ulimit -a getconf PATH_MAX . getconf NAME_MAX .

Conclusion

The mkdir command is fundamental to filesystem organization and mastering it involves understanding:

Key Takeaways

  1. Basic Operations: Creating single or multiple directories
  2. Parent Creation: -p for creating intermediate directories
  3. Permissions: -m for setting modes at creation
  4. Verbose Mode: -v for feedback
  5. Error Handling: Dealing with existing directories and permissions
  6. Brace Expansion: Efficiently creating multiple directories
  7. Integration: Working with find, xargs, and other commands
  8. Scripting: Robust patterns for scripts
  9. Security: Proper permissions and validation
  10. Performance: Efficient bulk creation techniques

Best Practices Summary

  1. Use -p in scripts to ensure parent directories exist
  2. Set explicit permissions with -m for security
  3. Check return codes in scripts
  4. Validate directory names before creation
  5. Use variables for paths
  6. Create temporary directories with mktemp
  7. Handle errors gracefully
  8. Use brace expansion for multiple directories
  9. Consider umask settings
  10. Test with -v during development

The mkdir command may seem simple, but its proper use is crucial for system administration, script writing, and maintaining organized file systems.

Complete Bash Exercises with Solutions

Practice Bash scripting with solved exercises to improve your command-line and scripting skills.
Link: https://macronepal.com/complete-bash-exercises-with-solutions/

Complete Guide to Bash Crontab Command

Learn how to schedule and automate tasks efficiently using the Bash crontab command.
Link: https://macronepal.com/complete-guide-to-bash-crontab-command-schedule-tasks/

Complete Guide to Bash Arrays

Understand how to create, manage, and use arrays in Bash scripting.
Link: https://macronepal.com/complete-guide-to-bash-arrays/

Bash Quiz: Test Your Knowledge

Test your Bash scripting knowledge with quizzes and practical questions.
Link: https://macronepal.com/bash-quiz-test-your-knowledge/

Complete Guide to Bash Functions

Learn how to write reusable Bash functions for cleaner and efficient scripts.
Link: https://macronepal.com/complete-guide-to-bash-functions/

Complete Guide to Bash Loops

Master loops in Bash for repetitive tasks and automation.
Link: https://macronepal.com/complete-guide-to-bash-loops/

Complete Guide to Bash If-Else Statements

Learn decision-making in Bash using conditional statements.
Link: https://macronepal.com/complete-guide-to-bash-ifelse-statements/

Complete Guide to Bash Operators

Explore arithmetic, logical, and comparison operators in Bash.
Link: https://macronepal.com/complete-guide-to-bash-operators/

Complete Guide to Bash Data Types

Understand variables and different data types used in Bash scripting.
Link: https://macronepal.com/complete-guide-to-bash-data-types/

Complete Guide to Bash Variables

Learn how to declare, assign, and use variables in Bash scripts.
Link: https://macronepal.com/complete-guide-to-bash-variables/

Complete Guide to Bash Scripting

A complete introduction to writing Bash scripts for automation.
Link: https://macronepal.com/complete-guide-to-bash-scripting/

Complete Guide to Basic Bash Syntax

Learn the fundamental syntax needed to write Bash commands and scripts.
Link: https://macronepal.com/complete-guide-to-basic-bash-syntax/

Complete Guide to Bash Chgrp Command

Learn how to change group ownership of files and directories.
Link: https://macronepal.com/complete-guide-to-bash-chgrp-command-change-group-ownership-2/

Complete Guide to Bash Chgrp Command (Alternate)

Another detailed explanation of Bash group ownership management.
Link: https://macronepal.com/complete-guide-to-bash-chgrp-command-change-group-ownership/

Complete Guide to Bash File Permissions and Ownership

Understand Linux file permissions and ownership management.
Link: https://macronepal.com/complete-guide-to-bash-file-permissions-and-ownership/

Complete Guide to Bash Chmod Command

Learn how to modify file permissions using chmod.
Link: https://macronepal.com/complete-guide-to-bash-chmod-command-change-file-permissions/

Complete Guide to Bash Chown Command

Change file ownership using the Bash chown command.
Link: https://macronepal.com/complete-guide-to-bash-chown-command-change-file-ownership/

Complete Guide to Bash SCP Command

Securely transfer files between systems using SCP.
Link: https://macronepal.com/complete-guide-to-bash-scp-command-secure-copy/

Complete Guide to Bash SSH Command

Learn secure remote access and server management using SSH.
Link: https://macronepal.com/complete-guide-to-bash-ssh-command/

Bash Wget Command Complete Guide

Download files from the internet using the wget command.
Link: https://macronepal.com/bash-wget-command-complete-guide-to-non-interactive-network-downloader/

Leave a Reply

Your email address will not be published. Required fields are marked *


Macro Nepal Helper