Overview
The readlink command is used to find the “actual file path” that a symbolic link (shortcut) points to. While you can check a link’s target with ls -l, readlink is better for shell scripts because it outputs only the path itself. By using the -f option, you can follow multiple layers of links and convert relative paths into full absolute paths.
Specifications (Arguments and Options)
Syntax
readlink [options] filename
Main Arguments and Options
| Option | Description |
-f | Follows all links recursively and outputs the full absolute path (canonicalize). |
-e | Like -f, but all parts of the path must actually exist on the system. |
-m | Like -f, but does not check if the file or directory actually exists. |
-n | Do not output the trailing newline character. |
-z | Use a null character (\0) at the end of the output instead of a newline. |
-q, -s | Quiet mode; do not display error messages. |
Basic Usage
When used without options, it shows the path stored in the symbolic link. If it is a relative path, it will display it as-is.
Command
# Check where the symbolic link "current_app" points to
readlink current_app
Execution Result
./versions/v1.0.2
Practical Commands
Resolve Nested Links and Get Absolute Paths
If a link points to another link (nested links) or uses a relative path, the -f option allows you to get the final absolute path immediately. This is the most common use case.
# Find the final actual path of /usr/bin/editor
# Example: editor -> /etc/alternatives/editor -> /usr/bin/vim.basic
readlink -f /usr/bin/editor
Output:
/usr/bin/vim.basic
Verify Link Targets (For Scripts)
The -e option returns an exit status of 1 (failure) if the target file does not exist (broken link). You can use this to check if a link is valid before running a process.
# Check if the target of the link exists
# For a valid link:
readlink -e /usr/bin/python3
echo "Status: $?"
# For a broken link or non-existent file:
readlink -e /usr/bin/invalid_link
echo "Status: $?"
Output:
/usr/bin/python3.10
Status: 0
Status: 1
Note: If the status is 1, the command produces no text output.
Customization Points
- Absolute Path Conversion: If you provide a normal file instead of a symbolic link,
readlink -fwill return the full absolute path of that file. - Shell Scripting: This command works well with variable assignment. You can normalize paths using
REAL_PATH=$(readlink -f "$TARGET_FILE").
Important Notes
- macOS (BSD) Differences: The version of
readlinkin Linux (GNU) and macOS (BSD) behave differently. The BSD version often lacks the-foption. For scripts that need to work on both, consider using therealpathcommand instead. - Choosing between -f and -m: If you want to find the absolute path for a file or directory that you are about to create (which does not exist yet), use
-minstead of-for-e.
Application: Get the Directory of the Script Itself
This is a common “idiom” used to find the directory where the script is located, no matter where it is executed from.
#!/bin/bash
# Get the absolute path of this script and extract the directory part
SCRIPT_DIR=$(dirname "$(readlink -f "$0")")
echo "Script location: $SCRIPT_DIR"
# You can then load files like $SCRIPT_DIR/config.conf
Summary
The readlink command, especially with the -f option, saves you the trouble of manually tracing complex directory structures and symbolic links. It provides the “correct path” as recognized by the system. Along with pwd and ls, it is a fundamental tool for path resolution in robust shell scripts.
