How to Check if File is Readable
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
| Operator | Tests | Usage | Returns True If |
|---|---|---|---|
| -r | Readable | [ -r "$file" ] | File readable |
| -w | Writable | [ -w "$file" ] | File writable |
| -x | Executable | [ -x "$file" ] | File executable |
| -f -r | File + readable | [ -f "$f" -a -r "$f" ] | Regular file AND readable |
| -s -r | Size + 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:
| Operator | Meaning | Example |
|---|---|---|
-r | Readable | [ -r file ] |
-w | Writable | [ -w file ] |
-x | Executable | [ -x file ] |
-f | Regular file | [ -f file ] |
-d | Directory | [ -d file ] |
-e | Exists | [ -e file ] |
-s | Exists and not empty | [ -s file ] |
-z | String 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
-fto check for regular files (not directories) - Use
-dto check for directories -echecks 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.