How to Resolve Canonical File Paths and Symlinks in Linux Using realpath

When developing Bash automation scripts, managing nested system configuration directories, or auditing symbolic links across modern filesystems, relative paths like ../../opt/app/./config/../bin/script.sh frequently cause confusion. If a shell script changes the working directory using cd, any unresolved relative paths break immediately.

While historically administrators relied on readlink -f to expand links, modern Linux environments provide a dedicated, POSIX-compliant standard utility: realpath. Included natively within GNU Coreutils, realpath expands all relative dot segments, resolves multi-hop symlink chains recursively, removes redundant slashes, and outputs the absolute, canonical path to any filesystem object.


How realpath Operates and Compares with readlink

Understanding how realpath evaluates paths highlights why it has replaced older workarounds in enterprise shell scripting:

Feature realpath (GNU Coreutils) readlink (Legacy Utility)
Primary Purpose Canonicalizes any arbitrary pathname, whether it contains symlinks, relative dots, or standard directories. Originally built solely to print the raw target value of a symbolic link.
Missing Path Handling Offers -m (canonicalize-missing) and -e (canonicalize-existing) switches for strict validation. Behaviour varies widely between GNU, BSD, and macOS versions without flags.
Relative Path Computation Native --relative-to and --relative-base flags to calculate relative paths between two directories. Unsupported; requires complex string manipulation in sed or awk.

Basic realpath Usage and Resolving Relative Paths

Passing any file or directory path containing redundant segments (such as single dots . or parent dots ..) cleans up the path into an authoritative absolute path:

realpath ../../etc/nginx/./nginx.conf

Sample output:

/etc/nginx/nginx.conf

Even if you pass a simple filename in your current working folder, realpath prepends the full absolute path:

realpath backup.tar.gz

Outputs: /home/admin/deployments/backup.tar.gz


Unraveling Symbolic Links Recursively

In Linux, package managers and container runtimes frequently stack symbolic links (for example, /usr/bin/python pointing to /usr/bin/python3, which points to /usr/bin/python3.12). Running realpath traverses the entire chain and returns the physical destination binary:

realpath /usr/bin/python3

Sample output:

/usr/bin/python3.12

If you need to resolve symlinks without requiring the destination target to exist on disk at the moment of execution, use the -m (canonicalize-missing) parameter:

realpath -m /var/run/unmounted_drive/future_file.log

Computing Relative Paths Between Two Directories

One of the most powerful capabilities of realpath is computing how to navigate from one directory to another using relative notation. This is invaluable when writing build scripts, creating relative symlinks in Git repositories, or generating portable web assets.

Use the --relative-to parameter:

realpath --relative-to=/var/www/html /var/log/nginx/access.log

Sample output:

../../log/nginx/access.log

The command calculates precisely how many steps upward (../../) and across into adjacent folders are required to bridge the two locations.


Practical Shell Script Integration

When writing Bash scripts, you frequently need to identify the exact directory where the running script resides, regardless of which folder the user invoked it from:

#!/usr/bin/env bash
SCRIPT_DIR=$(dirname "$(realpath "$0")")
echo "Script directory is: ${SCRIPT_DIR}"

By wrapping "$0" in realpath, your script reliably resolves symlinks created in /usr/local/bin back to its true source repository directory.

Combined with tools like visualising directory trees with tree or using chmod and chown reference flags, mastering realpath ensures your file handling scripts remain rock-solid and impervious to path resolution errors.

Get the best tech tips delivered straight to your inbox.

Join thousands of readers mastering Apple, Google, Microsoft, and Linux.