Problem Statement
Explain file testing operators in bash. How do you check if files exist, are readable, writable, directories, etc.?
Explanation
File test operators used with test command ([ ]) or [[ ]]: -e file tests if file exists (any type), -f file tests if regular file exists, -d file tests if directory exists, -L file tests if symbolic link exists, -b file tests if block device, -c file tests if character device, -p file tests if named pipe, -S file tests if socket.
Permission tests: -r file tests if readable, -w file tests if writable, -x file tests if executable, -O file tests if owned by current user, -G file tests if owned by current group. These check effective permissions considering user, group, and others.
File comparison: file1 -nt file2 tests if file1 newer than file2 (modification time), file1 -ot file2 tests if older, -ef tests if same file (same inode). Size test: -s file tests if file has size greater than zero (non-empty). Example:
```bash
if [ -f "$FILE" ] && [ -r "$FILE" ]; then
cat "$FILE"
else
echo "File doesn't exist or not readable"
fi
```
Combining tests: use && (AND), || (OR), ! (NOT). Example: [ -f file ] && [ ! -w file ] tests if file exists and not writable. In [[ ]], use built-in && and ||: [[ -f file && -r file ]]. The [[ ]] construct is bash-specific but more powerful than [ ], supporting pattern matching and regex.
Common patterns: check before operations [ -d "$DIR" ] || mkdir "$DIR" creates directory if doesn't exist, [ ! -f "$FILE" ] && touch "$FILE" creates file if doesn't exist, validate input: [ -z "$VAR" ] tests if variable empty. Proper file testing prevents errors from missing files, wrong permissions, or incorrect file types.