Complete Guide to Bash chmod Command (Change File Permissions)

Introduction to chmod

The chmod (change mode) command is a fundamental Unix/Linux utility used to set and modify file and directory permissions. Understanding chmod is essential for system security, file sharing, and proper system operation.

Key Concepts

  • File Permissions: Read (r), Write (w), Execute (x)
  • User Classes: Owner (u), Group (g), Others (o)
  • Numeric Mode: Permissions represented as octal numbers (e.g., 755, 644)
  • Symbolic Mode: Permissions modified using symbols (e.g., u+x, go-w)
  • Special Permissions: Setuid, Setgid, Sticky bit

1. Basic Concepts and Syntax

Understanding File Permissions

# View file permissions
ls -l filename
# Output: -rw-r--r-- 1 user group 1024 Mar 12 10:00 filename
#          ^^^^^^^
#          ||||||||
#          |||||└── others permissions
#          ||||└── group permissions
#          |||└── owner permissions
#          |└── file type
#          └── permissions string
# Permission breakdown
# Position 1: File type (- = regular file, d = directory, l = symlink)
# Positions 2-4: Owner permissions (rwx)
# Positions 5-7: Group permissions (rwx)
# Positions 8-10: Others permissions (rwx)
# Example: -rwxr-xr--
# Owner: read, write, execute
# Group: read, execute
# Others: read only

Basic Syntax

# Basic syntax
chmod [options] mode file
# Numeric mode (octal)
chmod 755 script.sh
chmod 644 document.txt
chmod 700 private/
# Symbolic mode
chmod u+x script.sh        # Add execute for owner
chmod go-w document.txt    # Remove write for group and others
chmod a+r readme.txt       # Add read for all (owner, group, others)
# Recursive change
chmod -R 755 directory/
chmod -R u+w directory/
# Verbose output
chmod -v 644 file.txt      # Show what changes are made

2. Numeric (Octal) Mode

Understanding Octal Permissions

# Octal values
# Read (r) = 4
# Write (w) = 2
# Execute (x) = 1
# --- = 0
# Common combinations
# 7 = 4+2+1 = rwx (read, write, execute)
# 6 = 4+2   = rw- (read, write)
# 5 = 4+1   = r-x (read, execute)
# 4 = 4     = r-- (read only)
# 3 = 2+1   = -wx (write, execute)
# 2 = 2     = -w- (write only)
# 1 = 1     = --x (execute only)
# 0 = 0     = --- (no permissions)
# Three-digit notation: owner-group-others
chmod 754 file.txt
# 7 (owner): rwx (4+2+1)
# 5 (group): r-x (4+1)
# 4 (others): r-- (4)
# Four-digit notation: includes special permissions
chmod 2755 script.sh
# 2: setgid bit
# 7: owner permissions
# 5: group permissions
# 5: others permissions

Common Octal Permissions

# Common permission sets
chmod 600 file.txt          # Owner: rw-, Group: ---, Others: --- (private file)
chmod 644 file.txt          # Owner: rw-, Group: r--, Others: r-- (default file)
chmod 664 file.txt          # Owner: rw-, Group: rw-, Others: r-- (shared file)
chmod 700 file.txt          # Owner: rwx, Group: ---, Others: --- (private executable)
chmod 755 file.txt          # Owner: rwx, Group: r-x, Others: r-x (default executable)
chmod 777 file.txt          # Owner: rwx, Group: rwx, Others: rwx (all access - DANGEROUS!)
# Directory permissions
chmod 755 directory/        # Owner: rwx, Group: r-x, Others: r-x (standard directory)
chmod 700 directory/        # Owner: rwx, Group: ---, Others: --- (private directory)
chmod 750 directory/        # Owner: rwx, Group: r-x, Others: --- (group directory)
chmod 777 directory/        # Everyone can read/write/execute - DANGEROUS!
# Special cases
chmod 555 script.sh         # Everyone can read/execute, no write
chmod 000 file.txt          # No permissions for anyone
chmod 111 file.txt          # Execute only for everyone

3. Symbolic Mode

Basic Symbolic Operations

# User classes
# u = owner (user)
# g = group
# o = others
# a = all (ugo)
# Operations
# + = add permission
# - = remove permission
# = = set exactly
# Add permissions
chmod u+x script.sh         # Add execute for owner
chmod g+w file.txt          # Add write for group
chmod o+r file.txt          # Add read for others
chmod a+x script.sh         # Add execute for all
# Remove permissions
chmod u-x script.sh         # Remove execute from owner
chmod g-w file.txt          # Remove write from group
chmod o-r file.txt          # Remove read from others
chmod a-x script.sh         # Remove execute from all
# Set exact permissions
chmod u=rwx script.sh       # Set owner to rwx
chmod g=rx script.sh        # Set group to r-x
chmod o=r script.sh         # Set others to r--
chmod a=r file.txt          # Set all to read-only
# Multiple changes at once
chmod u+rwx,g+rx,o+r script.sh
chmod u=rwx,g=rx,o=r script.sh
chmod ugo+x script.sh       # Same as a+x

Advanced Symbolic Operations

# Copy permissions from one class to another
chmod g=u file.txt          # Set group permissions equal to owner
chmod o=u file.txt          # Set others permissions equal to owner
chmod o=g file.txt          # Set others permissions equal to group
# Multiple changes with reference
chmod --reference=template.txt target.txt
# Recursive symbolic changes
chmod -R u+w directory/     # Add write for owner to all files/dirs
chmod -R go-w directory/    # Remove write for group/others
# Conditional changes (find + chmod)
find . -type f -exec chmod 644 {} \;     # Set all files to 644
find . -type d -exec chmod 755 {} \;     # Set all directories to 755
find . -name "*.sh" -exec chmod +x {} \; # Make all shell scripts executable
# Execute only if file is a directory
chmod u+X *                 # Add execute only for directories

4. Special Permissions

Setuid, Setgid, and Sticky Bit

# Special permission values (4-digit octal)
# 4 = setuid (s/S) - user ID on execution
# 2 = setgid (s/S) - group ID on execution
# 1 = sticky (t/T) - restricted deletion
# Setuid (user ID on execution)
chmod 4755 script.sh        # -rwsr-xr-x (setuid)
chmod u+s script.sh         # Symbolic form
# Setgid (group ID on execution)
chmod 2755 script.sh        # -rwxr-sr-x (setgid)
chmod g+s script.sh         # Symbolic form
# Sticky bit (restricted deletion)
chmod 1777 /tmp             # drwxrwxrwt (sticky bit)
chmod +t /tmp               # Symbolic form
# Multiple special bits
chmod 6755 script.sh        # -rwsr-sr-x (setuid + setgid)
chmod 7755 script.sh        # -rwsr-sr-t (all special bits)
# Display special permissions in ls
ls -l /tmp
# drwxrwxrwt  ...  # t indicates sticky bit
# -rwsr-xr-x  ...  # s indicates setuid
# -rwxr-sr-x  ...  # s indicates setgid

Practical Examples of Special Permissions

# Setuid example (for programs that need root privileges)
sudo chmod 4755 /usr/bin/passwd
# -rwsr-xr-x 1 root root ... /usr/bin/passwd
# Setgid on directories (new files inherit group)
chmod g+s shared_directory/
chmod 2755 shared_directory/
# Sticky bit on shared directories (only owner can delete)
chmod +t /tmp
chmod 1777 /tmp
# Creating a shared group workspace
mkdir /project
chgrp projectgroup /project
chmod 2775 /project          # setgid + rwx for owner/group
# Now all new files in /project inherit the 'projectgroup' group

5. Practical Examples

File Management Scripts

#!/bin/bash
# Set up a new project with proper permissions
setup_project() {
local project_dir="$1"
local group="${2:-developers}"
echo "Setting up project: $project_dir"
# Create directory structure
mkdir -p "$project_dir"/{src,docs,tests,bin}
# Set group ownership
chgrp -R "$group" "$project_dir"
# Set directory permissions
find "$project_dir" -type d -exec chmod 2775 {} \;  # setgid + rwx for group
# Set file permissions
find "$project_dir" -type f -exec chmod 664 {} \;   # rw for owner/group
# Make scripts executable
find "$project_dir/bin" -type f -exec chmod 775 {} \;
find "$project_dir" -name "*.sh" -exec chmod 775 {} \;
echo "Project setup complete"
ls -la "$project_dir"
}
# Secure home directory
secure_home() {
local home="${1:-$HOME}"
echo "Securing $home"
# Home directory should be 750 or 700
chmod 750 "$home"
# .ssh directory should be 700
if [ -d "$home/.ssh" ]; then
chmod 700 "$home/.ssh"
chmod 600 "$home/.ssh/"* 2>/dev/null
chmod 644 "$home/.ssh/"*.pub 2>/dev/null
fi
# Private files should be 600
find "$home" -name "*.key" -o -name "*.pem" -o -name "*secret*" \
-exec chmod 600 {} \; 2>/dev/null
echo "Security permissions applied"
}
# Fix permissions after copying from Windows
fix_permissions() {
local dir="${1:-.}"
echo "Fixing permissions in $dir"
# Directories: 755
find "$dir" -type d -exec chmod 755 {} \;
# Regular files: 644
find "$dir" -type f -not -name "*.sh" -not -name "*.pl" -not -name "*.py" \
-exec chmod 644 {} \;
# Scripts: 755
find "$dir" -name "*.sh" -o -name "*.pl" -o -name "*.py" -o -name "*.exe" \
-exec chmod 755 {} \;
echo "Permissions fixed"
}

Permission Checking and Validation

#!/bin/bash
# Check if file has specific permissions
check_permissions() {
local file="$1"
local required="$2"  # e.g., "rwxr-xr-x"
current=$(ls -l "$file" | cut -c2-10)
if [ "$current" = "$required" ]; then
echo "✓ Permissions match"
return 0
else
echo "✗ Permissions mismatch"
echo "  Required: $required"
echo "  Current:  $current"
return 1
fi
}
# Validate file is secure
validate_security() {
local file="$1"
perms=$(stat -c %a "$file")
owner=$(stat -c %U "$file")
if [ "$owner" != "$USER" ] && [ "$owner" != "root" ]; then
echo "⚠ File owned by $owner, not $USER"
fi
if [ -f "$file" ] && [ "$perms" -gt "644" ]; then
echo "⚠ File permissions too permissive: $perms"
fi
if [ -d "$file" ] && [ "$perms" -gt "755" ]; then
echo "⚠ Directory permissions too permissive: $perms"
fi
}
# Test if file is executable
is_executable() {
local file="$1"
if [ -x "$file" ]; then
echo "✓ $file is executable"
return 0
else
echo "✗ $file is not executable"
return 1
fi
}
# Check write permissions
check_writable() {
local file="$1"
if [ -w "$file" ]; then
echo "✓ Can write to $file"
else
echo "✗ Cannot write to $file"
fi
}

6. Recursive Operations

Recursive chmod Examples

# Change all files to 644, directories to 755
find /path -type f -exec chmod 644 {} \;
find /path -type d -exec chmod 755 {} \;
# Using xargs for better performance
find /path -type f -print0 | xargs -0 chmod 644
find /path -type d -print0 | xargs -0 chmod 755
# Make all shell scripts executable recursively
find . -name "*.sh" -exec chmod +x {} \;
# Add group write to all files in a directory
chmod -R g+w /shared/directory/
# Remove world read from everything
chmod -R o-r /private/directory/
# Set all files to read-only for group/others
chmod -R go-w,go-r ~/documents/
# Using find with complex conditions
find /project -type f -not -perm 644 -exec chmod 644 {} \;
find /project -type d -not -perm 755 -exec chmod 755 {} \;

Selective Recursive Changes

#!/bin/bash
# Recursively change permissions based on file type
smart_chmod() {
local dir="$1"
# Set directories to 755
find "$dir" -type d -exec chmod 755 {} \;
# Set regular files to 644
find "$dir" -type f \
-not -name "*.sh" \
-not -name "*.pl" \
-not -name "*.py" \
-not -perm -111 \
-exec chmod 644 {} \;
# Set executable files to 755
find "$dir" -type f \( \
-name "*.sh" -o \
-name "*.pl" -o \
-name "*.py" -o \
-name "*.bin" -o \
-perm /111 \) \
-exec chmod 755 {} \;
# Set configuration files to 600
find "$dir" -type f \( \
-name "*.conf" -o \
-name "*.cfg" -o \
-name "*.key" -o \
-name "*.pem" \) \
-exec chmod 600 {} \;
}
# Apply permissions with dry run
dry_run_chmod() {
local perms="$1"
local path="$2"
find "$path" -type f -print | while read file; do
current=$(stat -c %a "$file")
if [ "$current" != "$perms" ]; then
echo "Would change $file from $current to $perms"
fi
done
}
# Change permissions only on files owned by specific user
chown_user_chmod() {
local user="$1"
local perms="$2"
local path="$3"
find "$path" -user "$user" -exec chmod "$perms" {} \;
}

7. Scripting with chmod

Permission Functions

#!/bin/bash
# Function to get current permissions in octal
get_permissions() {
local file="$1"
stat -c %a "$file" 2>/dev/null || stat -f %A "$file" 2>/dev/null
}
# Function to get permissions in symbolic form
get_symbolic() {
local file="$1"
ls -l "$file" | awk '{print $1}'
}
# Save and restore permissions
save_permissions() {
local file="$1"
local savefile="${2:-/tmp/permissions.txt}"
echo "$file:$(get_permissions "$file")" >> "$savefile"
}
restore_permissions() {
local savefile="${1:-/tmp/permissions.txt}"
while IFS=: read file perms; do
if [ -e "$file" ]; then
chmod "$perms" "$file"
echo "Restored $file to $perms"
fi
done < "$savefile"
}
# Ensure minimum permissions
ensure_min_perms() {
local file="$1"
local min_perms="$2"
current=$(get_permissions "$file")
# Simple comparison (works for 3-digit octal)
if [ "$current" -lt "$min_perms" ] 2>/dev/null; then
echo "Increasing $file from $current to $min_perms"
chmod "$min_perms" "$file"
fi
}

Permission Validation Script

#!/bin/bash
# Comprehensive permission validator
validate_permissions() {
local path="$1"
local report_file="${2:-/tmp/perm_report.txt}"
{
echo "Permission Validation Report"
echo "============================"
echo "Path: $path"
echo "Date: $(date)"
echo
# Find files with world-writable permissions
echo "World-writable files:"
find "$path" -type f -perm -002 -ls 2>/dev/null | head -20
echo
# Find directories with world-writable (without sticky bit)
echo "World-writable directories (without sticky bit):"
find "$path" -type d -perm -002 -a ! -perm -1000 -ls 2>/dev/null | head -20
echo
# Find files with setuid/setgid
echo "Setuid/setgid files:"
find "$path" -type f \( -perm -4000 -o -perm -2000 \) -ls 2>/dev/null | head -20
echo
# Find executable files owned by root
echo "Root-owned executable files:"
find "$path" -type f -user root -perm /111 -ls 2>/dev/null | head -20
echo
# Check home directory permissions
if [ -d "$HOME" ]; then
echo "Home directory permissions:"
ls -ld "$HOME"
fi
} > "$report_file"
echo "Report saved to $report_file"
}
# Quick security scan
security_scan() {
local critical_files=(
"/etc/passwd:644"
"/etc/shadow:600"
"/etc/ssh/sshd_config:600"
"/etc/sudoers:440"
)
for entry in "${critical_files[@]}"; do
file="${entry%%:*}"
expected="${entry#*:}"
if [ -f "$file" ]; then
current=$(stat -c %a "$file")
if [ "$current" != "$expected" ]; then
echo "⚠ $file has permissions $current (expected $expected)"
else
echo "✓ $file OK"
fi
fi
done
}

8. Integration with Other Commands

With find for Advanced Operations

# Find and fix files with incorrect permissions
find /var/www -type f -not -perm 644 -exec chmod 644 {} \;
find /var/www -type d -not -perm 755 -exec chmod 755 {} \;
# Make all newly created files group-writable
find /shared -type f -mtime -1 -exec chmod g+w {} \;
# Remove execute permission from all files except directories
find . -type f -exec chmod -x {} \;
# Add execute only to files that are already executable
find . -type f -perm /111 -exec chmod +x {} \;
# Complex permission fixes
find /project -type f \( \
-name "*.sh" -o \
-name "*.pl" -o \
-name "*.py" \) \
-exec chmod 755 {} \;
# Using -ok for confirmation
find . -name "*.conf" -ok chmod 644 {} \;

With chown and chgrp

# Combine ownership and permission changes
chown -R user:group directory/
chmod -R 755 directory/
# Set group and permissions together
chgrp -R developers /project
chmod -R 2775 /project
# Fix ownership and permissions for web files
chown -R www-data:www-data /var/www/
find /var/www -type f -exec chmod 644 {} \;
find /var/www -type d -exec chmod 755 {} \;
# User migration script
migrate_user() {
local old_user="$1"
local new_user="$2"
local dir="${3:-/home/$new_user}"
find "$dir" -user "$old_user" -exec chown "$new_user" {} \;
find "$dir" -group "$old_user" -exec chgrp "$new_user" {} \;
}

9. Troubleshooting and Error Handling

Common Issues and Solutions

#!/bin/bash
# Permission denied errors and fixes
fix_permission_denied() {
local file="$1"
if [ ! -e "$file" ]; then
echo "File does not exist: $file"
return 1
fi
if [ ! -r "$file" ]; then
echo "Adding read permission: $file"
chmod +r "$file"
fi
if [ ! -w "$file" ] && [ -d "$file" ]; then
echo "Adding write permission: $file"
chmod +w "$file"
fi
if [ -d "$file" ] && [ ! -x "$file" ]; then
echo "Adding execute permission to directory: $file"
chmod +x "$file"
fi
if [ -f "$file" ] && [ "${file##*.}" = "sh" ] && [ ! -x "$file" ]; then
echo "Making script executable: $file"
chmod +x "$file"
fi
}
# Debug permission issues
debug_permissions() {
local file="$1"
echo "=== Permission Debug: $file ==="
echo "Exists: $([ -e "$file" ] && echo "Yes" || echo "No")"
if [ -e "$file" ]; then
echo "Type: $([ -f "$file" ] && echo "File") $([ -d "$file" ] && echo "Directory")"
echo "Permissions: $(ls -l "$file" | awk '{print $1}')"
echo "Octal: $(stat -c %a "$file")"
echo "Owner: $(stat -c %U "$file")"
echo "Group: $(stat -c %G "$file")"
echo "Size: $(stat -c %s "$file")"
echo "Readable: $([ -r "$file" ] && echo "Yes" || echo "No")"
echo "Writable: $([ -w "$file" ] && echo "Yes" || echo "No")"
echo "Executable: $([ -x "$file" ] && echo "Yes" || echo "No")"
fi
}

Error Handling in Scripts

#!/bin/bash
# Safe chmod function
safe_chmod() {
local perms="$1"
local file="$2"
# Validate permissions format
if ! [[ "$perms" =~ ^[0-7]{3,4}$ ]] && ! [[ "$perms" =~ ^[ugoa]*[-+=][rwx]*$ ]]; then
echo "Error: Invalid permission format: $perms" >&2
return 1
fi
# Check if file exists
if [ ! -e "$file" ]; then
echo "Error: File not found: $file" >&2
return 1
fi
# Save original permissions
orig_perms=$(stat -c %a "$file" 2>/dev/null)
# Attempt to change permissions
if chmod "$perms" "$file" 2>/tmp/chmod_error.$$; then
echo "✓ Changed $file to $perms"
return 0
else
echo "✗ Failed to change $file permissions" >&2
cat /tmp/chmod_error.$$ >&2
rm /tmp/chmod_error.$$
return 1
fi
}
# Try to change permissions with escalation
chmod_with_escalation() {
local perms="$1"
local file="$2"
# Try normal
if chmod "$perms" "$file" 2>/dev/null; then
return 0
fi
# Try with sudo
if command -v sudo >/dev/null && sudo -n true 2>/dev/null; then
echo "Attempting with sudo..."
sudo chmod "$perms" "$file"
return $?
fi
echo "Failed to change permissions (try as root)" >&2
return 1
}

10. Advanced Techniques

ACL (Access Control Lists)

# Note: Requires ACL support
# View ACL
getfacl file.txt
# Set ACL
setfacl -m u:username:rwx file.txt
setfacl -m g:groupname:rx file.txt
# Remove ACL
setfacl -x u:username file.txt
# Recursive ACL
setfacl -R -m u:username:rwx directory/
# Default ACL for new files
setfacl -d -m u:username:rwx directory/

Umask and Default Permissions

# View current umask
umask
# Output: 0022
# Set umask (affects new files)
umask 022   # Files: 644, Dirs: 755
umask 002   # Files: 664, Dirs: 775
umask 077   # Files: 600, Dirs: 700
# Calculate file permissions from umask
# File base: 666 - umask
# Dir base:  777 - umask
# Set umask in scripts
#!/bin/bash
(umask 077 && touch private.txt)
# Temporary umask change
old_umask=$(umask)
umask 077
touch secret.txt
umask "$old_umask"

Mass Permission Changes

#!/bin/bash
# Change permissions for all files of certain types
mass_chmod() {
local pattern="$1"
local perms="$2"
local dir="${3:-.}"
find "$dir" -type f -name "$pattern" -exec chmod "$perms" {} \;
echo "Changed permissions for $pattern files to $perms"
}
# Normalize permissions in a directory tree
normalize_perms() {
local dir="$1"
echo "Normalizing permissions in $dir"
# Directories: 755
find "$dir" -type d -exec chmod 755 {} \;
# Regular files: 644
find "$dir" -type f -exec chmod 644 {} \;
# Executable files: 755
find "$dir" -type f -name "*.sh" -exec chmod 755 {} \;
# Config files: 640
find "$dir" -type f \( -name "*.conf" -o -name "*.cfg" \) -exec chmod 640 {} \;
# Private keys: 600
find "$dir" -type f \( -name "*.key" -o -name "*.pem" -o -name "*_rsa" \) \
-exec chmod 600 {} \;
}
# Batch permission report
permission_report() {
local dir="$1"
echo "Permission Report for $dir"
echo "=========================="
# Files with unusual permissions
echo "Files with non-standard permissions (not 644):"
find "$dir" -type f ! -perm 644 -ls 2>/dev/null | awk '{print $1, $11}' | head -20
echo -e "\nDirectories with non-standard permissions (not 755):"
find "$dir" -type d ! -perm 755 -ls 2>/dev/null | awk '{print $1, $11}' | head -20
}

11. Best Practices and Security

Security Guidelines

#!/bin/bash
# Security best practices
# 1. Never use 777 permissions
# 2. Use 755 for directories, 644 for files
# 3. Keep private files (ssh keys, passwords) at 600
# 4. Use sticky bit on shared directories
# 5. Be careful with setuid/setgid binaries
# Secure directory creation
secure_mkdir() {
local dir="$1"
mkdir -p "$dir"
chmod 750 "$dir"
}
# Secure file creation
secure_touch() {
local file="$1"
touch "$file"
chmod 600 "$file"
}
# Make script executable securely
secure_chmod_script() {
local script="$1"
if [ -f "$script" ] && [ -r "$script" ]; then
chmod 755 "$script"
echo "✓ Made $script executable (owner only write)"
fi
}
# Check for dangerous permissions
check_dangerous() {
local dir="${1:-/}"
echo "Scanning for dangerous permissions..."
# World-writable files
find "$dir" -type f -perm -002 2>/dev/null | while read file; do
echo "⚠ World-writable: $file"
done
# World-writable directories without sticky
find "$dir" -type d -perm -002 -a ! -perm -1000 2>/dev/null | while read dir; do
echo "⚠ Unsafe directory: $dir"
done
# Setuid root files
find "$dir" -type f -user root -perm -4000 2>/dev/null | while read file; do
echo "⚠ Setuid root: $file"
done
}

Production Environments

#!/bin/bash
# Web server permissions
setup_web_perms() {
local web_root="$1"
local web_user="${2:-www-data}"
local web_group="${3:-www-data}"
# Set ownership
chown -R "$web_user:$web_group" "$web_root"
# Directories: 755
find "$web_root" -type d -exec chmod 755 {} \;
# Files: 644
find "$web_root" -type f -exec chmod 644 {} \;
# Upload directories: 775
if [ -d "$web_root/uploads" ]; then
chmod 775 "$web_root/uploads"
fi
# Configuration files: 640
find "$web_root" -name "*.conf" -o -name "*.ini" -exec chmod 640 {} \;
}
# Database permissions
setup_db_perms() {
local db_dir="$1"
local db_user="${2:-mysql}"
chown -R "$db_user:$db_user" "$db_dir"
find "$db_dir" -type d -exec chmod 750 {} \;
find "$db_dir" -type f -exec chmod 640 {} \;
}
# Application deployment
deploy_app() {
local app_dir="$1"
local deploy_user="$2"
# Set base permissions
chown -R "$deploy_user:$(id -gn "$deploy_user")" "$app_dir"
find "$app_dir" -type d -exec chmod 755 {} \;
find "$app_dir" -type f -exec chmod 644 {} \;
# Make scripts executable
find "$app_dir" -name "*.sh" -o -name "*.pl" -o -name "*.py" \
-exec chmod 755 {} \;
# Secure configuration
find "$app_dir" -name "*.conf" -o -name "config.php" \
-exec chmod 640 {} \;
}

12. Command Summary and Cheat Sheet

Quick Reference

# Numeric mode examples
chmod 644 file.txt    # rw-r--r--
chmod 755 file.txt    # rwxr-xr-x
chmod 700 file.txt    # rwx------
chmod 600 file.txt    # rw-------
chmod 777 file.txt    # rwxrwxrwx (avoid!)
# Symbolic mode examples
chmod u+x file        # Add execute for owner
chmod go-w file       # Remove write for group/others
chmod a+r file        # Add read for all
chmod u=rwx,g=rx,o=r  # Set specific permissions
# Recursive operations
chmod -R 755 dir/
chmod -R u+w dir/
# Special permissions
chmod u+s file        # Setuid
chmod g+s dir         # Setgid on directory
chmod +t dir          # Sticky bit
# Common operations
chmod +x script.sh                    # Make executable
chmod -R g+w shared/                  # Add group write
chmod 700 ~/.ssh                       # Secure SSH directory
chmod 600 ~/.ssh/id_rsa                # Secure private key

Permission Quick Reference Table

# Numeric to Symbolic Conversion
# 0 = ---
# 1 = --x
# 2 = -w-
# 3 = -wx
# 4 = r--
# 5 = r-x
# 6 = rw-
# 7 = rwx
# Common Combinations
# 400 = r--------
# 600 = rw-------
# 644 = rw-r--r--
# 664 = rw-rw-r--
# 700 = rwx------
# 755 = rwxr-xr-x
# 775 = rwxrwxr-x
# 777 = rwxrwxrwx
# Directory Permissions Meaning
# r = can list contents
# w = can create/delete files
# x = can cd into directory

Permission Test Commands

# Test file permissions
[ -r file ] && echo "Readable"
[ -w file ] && echo "Writable"
[ -x file ] && echo "Executable"
# Test directory permissions
[ -r dir ] && echo "Can list"
[ -w dir ] && echo "Can create"
[ -x dir ] && echo "Can access"
# Compare permissions
[ $(stat -c %a file1) = $(stat -c %a file2) ] && echo "Same permissions"

Conclusion

The chmod command is essential for system security and file management:

Key Takeaways

  1. Three User Classes: Owner (u), Group (g), Others (o)
  2. Three Permissions: Read (r=4), Write (w=2), Execute (x=1)
  3. Two Modes: Numeric (octal) and Symbolic
  4. Special Bits: Setuid (4), Setgid (2), Sticky (1)
  5. Security: Always use least-privilege principle

Best Practices Summary

File TypeRecommended PermissionsCommand
Regular files644chmod 644 file
Executable files755chmod 755 script
Private files600chmod 600 secret
Directories755chmod 755 dir
Shared directories775chmod 775 shared
SSH private keys600chmod 600 ~/.ssh/id_rsa
SSH public keys644chmod 644 ~/.ssh/*.pub
Web directories755chmod 755 /var/www/html

Safety Rules

  1. Never use 777 on production systems
  2. Be careful with recursive changes - use -R cautiously
  3. Always backup before mass permission changes
  4. Test with -v to see what changes are made
  5. Use find for selective permission changes
  6. Regularly audit critical file permissions
  7. Set proper umask for new files

The chmod command, while simple in concept, requires careful consideration to maintain system security while ensuring proper functionality.

Leave a Reply

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


Macro Nepal Helper