Skip to main content

How to Check if File is Readable

• 3 min read
bash

Quick Answer: Check if File is Readable

To check if a file is readable in Bash, use the -r operator: if [ -r "$file" ]. This returns true if the file exists and your current user has read permission. Combine with -f to ensure it’s a regular file.

Quick Comparison: File Permission Testing

OperatorTestsUsageReturns True If
-rReadable[ -r "$file" ]File readable
-wWritable[ -w "$file" ]File writable
-xExecutable[ -x "$file" ]File executable
-f -rFile + readable[ -f "$f" -a -r "$f" ]Regular file AND readable
-s -rSize + readable[ -s "$f" -a -r "$f" ]Has content AND readable

Bottom line: Use -r for read permission, combine with -f for safety.


File Permission Testing

Before reading a file, it’s good practice to verify you have read permission. This prevents script failures and lets you handle permission issues gracefully. Bash provides several test operators to check file permissions and attributes.

Testing Read Permission

The -r operator checks if a file is readable:

#!/bin/bash

filename="/etc/passwd"

if [ -r "$filename" ]; then
  echo "$filename is readable"
else
  echo "$filename is not readable"
fi

This works with all file types: regular files, directories, symbolic links, etc.

The File Test Operators

Bash provides many file test operators. Here are the most common:

OperatorMeaningExample
-rReadable[ -r file ]
-wWritable[ -w file ]
-xExecutable[ -x file ]
-fRegular file[ -f file ]
-dDirectory[ -d file ]
-eExists[ -e file ]
-sExists and not empty[ -s file ]
-zString is empty[ -z "$var" ]

Checking Read and Write Permissions

Check if you can both read and write:

#!/bin/bash

logfile="/var/log/myapp.log"

# Check if readable AND writable
if [ -r "$logfile" ] && [ -w "$logfile" ]; then
  echo "Can read and write to log file"
  echo "New entry" >> "$logfile"
else
  echo "Insufficient permissions"
fi

# Modern style with [[ ]]
if [[ -r "$logfile" && -w "$logfile" ]]; then
  echo "File is readable and writable"
fi

Practical Example: Safe File Reading

Create a function that safely reads a file:

#!/bin/bash

safe_read_file() {
  local filename="$1"

  # Check if file exists
  if [ ! -e "$filename" ]; then
    echo "ERROR: File does not exist: $filename"
    return 1
  fi

  # Check if it's a regular file (not a directory)
  if [ ! -f "$filename" ]; then
    echo "ERROR: Not a regular file: $filename"
    return 1
  fi

  # Check if readable
  if [ ! -r "$filename" ]; then
    echo "ERROR: No read permission: $filename"
    return 1
  fi

  # Check if not empty
  if [ ! -s "$filename" ]; then
    echo "WARNING: File is empty"
    return 0
  fi

  # Safe to read
  cat "$filename"
  return 0
}

# Usage
safe_read_file "/etc/passwd"

Checking Directory Permissions

For directories, you typically check read and execute permissions:

#!/bin/bash

directory="/home/user"

# Check if directory is readable
if [ -r "$directory" ]; then
  echo "Can list directory contents"
fi

# Check if directory is writable
if [ -w "$directory" ]; then
  echo "Can create files in directory"
fi

# Check if directory is executable (can enter it)
if [ -x "$directory" ]; then
  echo "Can enter directory"
fi

Real-World Example: Configuration File Handler

#!/bin/bash

load_config() {
  local config_file="$1"
  local default_config="/etc/myapp/default.conf"

  # Try to load user config
  if [[ -f "$config_file" && -r "$config_file" ]]; then
    echo "Loading config from: $config_file"
    source "$config_file"
    return 0
  fi

  # Fall back to default config
  if [[ -f "$default_config" && -r "$default_config" ]]; then
    echo "Loading default config from: $default_config"
    source "$default_config"
    return 0
  fi

  # No config available
  echo "ERROR: No readable config file found"
  return 1
}

load_config "/home/user/.myapp/config"

Checking Executable Permission

Test if a file can be executed:

#!/bin/bash

# Check if file is executable
if [ -x "$1" ]; then
  echo "File is executable"
  ./"$1"
else
  echo "File is not executable or does not exist"
  exit 1
fi

Combining Multiple Checks

Check multiple conditions before processing:

#!/bin/bash

FILE="$1"

# All conditions must be true
if [[ -f "$FILE" && -r "$FILE" && -s "$FILE" ]]; then
  # File exists, is readable, and is not empty
  echo "Processing file: $FILE"
  wc -l "$FILE"
else
  # Detailed error reporting
  if [ ! -e "$FILE" ]; then
    echo "ERROR: File does not exist"
  elif [ ! -f "$FILE" ]; then
    echo "ERROR: Not a regular file"
  elif [ ! -r "$FILE" ]; then
    echo "ERROR: No read permission"
  elif [ ! -s "$FILE" ]; then
    echo "ERROR: File is empty"
  fi
  exit 1
fi

Checking Owner and Group

You can also test file ownership:

#!/bin/bash

# Check if file is owned by current user
if [ -O "/tmp/myfile" ]; then
  echo "You own this file"
fi

# Check if file belongs to current group
if [ -G "/tmp/myfile" ]; then
  echo "You are in this file's group"
fi

Practical Example: Log File Validator

#!/bin/bash

validate_log_directory() {
  local log_dir="$1"

  # Check directory exists and is readable
  if [ ! -r "$log_dir" ]; then
    echo "ERROR: Log directory not readable: $log_dir"
    return 1
  fi

  # Process each readable log file
  local count=0
  for logfile in "$log_dir"/*; do
    # Skip if not a file
    [ -f "$logfile" ] || continue

    # Skip if not readable
    [ -r "$logfile" ] || continue

    # Count readable log files
    ((count++))
    echo "✓ $(basename "$logfile")"
  done

  echo "Total readable log files: $count"
  return 0
}

# Usage
validate_log_directory "/var/log"

Important Notes

  • Always quote file variables: [ -r "$file" ] not [ -r $file ]
  • Use -f to check for regular files (not directories)
  • Use -d to check for directories
  • -e checks if anything exists (file, dir, link, etc.)
  • Permission checks respect your actual user, not just the file’s attributes
  • Reading files doesn’t require execute permission on the file itself, but does require read and execute on the parent directory

Quick Reference

# Check if readable
[ -r "$file" ]

# Check if writable
[ -w "$file" ]

# Check if executable
[ -x "$file" ]

# Check if regular file
[ -f "$file" ]

# Check if directory
[ -d "$file" ]

# Check if exists
[ -e "$file" ]

# Check if empty
[ ! -s "$file" ]

# Check readable and not empty
[ -r "$file" ] && [ -s "$file" ]

# Modern style: all at once
[[ -f "$file" && -r "$file" && -s "$file" ]]

Summary

Testing file permissions before operating on files is essential for robust scripts. The -r flag checks read permission, and you can combine it with other tests like -f (is a file), -d (is a directory), and -s (is not empty) to ensure safe file operations. Always quote your file variables and check permissions before attempting file operations.