readlink
Overview
The readlink command displays the target of symbolic links. It resolves symbolic links and shows where they point, essential for understanding link structures and debugging link issues.
Syntax
readlink [options] file...Common Options
| Option | Description |
|---|---|
-f |
Follow all symbolic links |
-e |
All components must exist |
-m |
No components need exist |
-n |
Don’t output trailing newline |
-q |
Suppress error messages |
-s |
Suppress non-error messages |
-v |
Verbose output |
-z |
End output with null character |
Key Use Cases
- Display symbolic link targets
- Resolve link chains
- Debug broken links
- Script path resolution
- Link validation
Examples with Explanations
Example 1: Basic Usage
readlink symlinkShows where the symbolic link points
Example 2: Follow All Links
readlink -f symlinkResolves all symbolic links in the path
Example 3: Canonical Path
readlink -e /usr/bin/pythonShows canonical path, fails if target doesn’t exist
Example 4: Multiple Files
readlink -f link1 link2 link3Resolves multiple symbolic links
Link Resolution
Single level:
readlink symlinkFull resolution:
readlink -f symlinkExisting files only:
readlink -e symlink
Common Usage Patterns
Check if file is a link:
if readlink "$file" >/dev/null 2>&1; then echo "$file is a symbolic link" fiGet script directory:
SCRIPT_DIR=$(dirname "$(readlink -f "$0")")Resolve configuration files:
CONFIG_FILE=$(readlink -f ~/.config/app.conf)
Script Applications
Portable script paths:
#!/bin/bash SCRIPT_PATH=$(readlink -f "$0") SCRIPT_DIR=$(dirname "$SCRIPT_PATH") cd "$SCRIPT_DIR"Link validation:
validate_link() { local link="$1" if ! readlink -e "$link" >/dev/null 2>&1; then echo "Broken link: $link" return 1 fi }
Performance Analysis
- Fast operation
- No file content reading
- Minimal system resources
- Good for path resolution
- Efficient link checking
Best Practices
- Use -f for complete resolution
- Check if target exists with -e
- Handle broken links gracefully
- Use in scripts for portability
- Combine with other path tools
Error Handling
Broken links:
if ! readlink -e "$link" >/dev/null 2>&1; then echo "Link is broken or doesn't exist" fiNot a symbolic link:
target=$(readlink "$file" 2>/dev/null) || { echo "$file is not a symbolic link" }
Integration Examples
Find broken links:
find /path -type l | while read link; do if ! readlink -e "$link" >/dev/null 2>&1; then echo "Broken: $link" fi doneLink maintenance:
for link in *.link; do target=$(readlink "$link") echo "$link -> $target" done
Advanced Usage
Quiet operation:
readlink -q symlinkNo trailing newline:
readlink -n symlinkNull-terminated output:
readlink -z symlink
Troubleshooting
- Permission denied errors
- Broken symbolic links
- Circular link references
- Non-existent targets
- Cross-filesystem links
Security Considerations
- Validate link targets
- Check for directory traversal
- Verify link ownership
- Monitor link changes
- Handle untrusted links carefully
Alternative Methods
Using ls:
ls -l symlink | awk '{print $NF}'Using stat:
stat -c %N symlinkUsing file:
file symlink
Real-world Examples
System administration:
# Check system links readlink /usr/bin/java readlink /etc/alternatives/editorDevelopment workflow:
# Resolve project paths PROJECT_ROOT=$(readlink -f "$(dirname "$0")/..")Configuration management:
# Verify config links for config in /etc/*.conf; do if [ -L "$config" ]; then echo "$config -> $(readlink "$config")" fi done