Linux realpath Command: Resolve Absolute and Canonical Paths
realpath is a command that outputs a normalized path by handling relative paths, . and .., redundant slashes, and symbolic links. It is useful for checking the actual location of a file, comparing how two paths are interpreted, or creating a relative path with respect to a base directory.
Whether path components must exist depends on -e, -E, and -m. Also, you cannot consider a file safely opened just based on the path calculation result, so separate caution is needed for security verification.
What is the realpath command?
realpath outputs the normalized file name or directory path. The typical result is an absolute path, and unnecessary /, ., .. components and symbolic links are handled.
realpath ./docs/../images/logo.webp
If the current working directory is /home/user/project, you might get results like the following.
/home/user/project/images/logo.webp
The exact result depends on the current working directory, the actual directory structure, and the configuration of symbolic links.
Basic Syntax and Usage
realpath [options] file...
If you specify multiple paths, the processed result of each is printed on a separate line.
realpath . realpath ../logs/app.log realpath /var//log/./nginx/../syslog
If you only need the physical path of the current directory, pwd -P is more direct. realpath can handle not only the current location but also multiple specified paths.
Choosing path existence conditions
In GNU realpath, you can choose with an option how much of the path must actually exist.
| Option | Existence conditions |
|---|---|
-E, --canonicalize |
Allow the last component to not exist. This is the default behavior of GNU, but it can be specified for portability. |
-e, --canonicalize-existing |
All path components including the last item must actually exist. |
-m, --canonicalize-missing |
Normalize the string assuming that missing intermediate components are directories. |
Allow only paths that exist with -e
realpath -e /etc/passwd realpath --canonicalize-existing /srv/app/config.yml
If even a single component is missing or inaccessible, it fails. It is useful when you only want to pass objects that actually exist to subsequent operations, but it does not prevent situations where the object changes immediately after the check.
Allow a missing final component with -E
realpath -E /srv/uploads/new-file.txt
The upper path can be checked, but this can be used in situations where the last file has not yet been created. It is the default behavior in GNU, but to reduce differences with the POSIX environment, it is better to indicate the intention with an option.
Allow missing path components with -m
realpath -m /srv/not-created/../future/file.txt
-m treats components that do not exist on the file system as directories. It is useful when precomputing path strings, but it does not guarantee that the output path actually exists or can be created.
Symbolic links and -L, -P, -s
Paths with .. and symbolic links together can end up in different locations depending on the processing order.
| Option | Action |
|---|---|
-P, --physical |
When encountering a symbolic link, it is interpreted, and then subsequent .. are processed. This is the default mode in GNU. |
-L, --logical |
Process the .. in the path string logically, then resolve symbolic links. |
-s, --strip, --no-symlinks |
Clean up just the dot components and duplicate slashes without following symbolic links. |
Check the physical path
realpath -P /srv/current/../shared
If /srv/current is a link pointing to another location, resolve its target first, then compute the parent path.
Preserve symbolic links and just clean up the string
realpath -s -m /srv/current/../shared
Using -s and -m together allows you to clean up the path string itself without following links in the actual file system. Do not use this combination when the actual target location is needed.
Output relative path
Specify the base directory with --relative-to
You can output the processed path as a relative path to a specific directory.
realpath --relative-to=/srv/www /srv/www/assets/css/site.css
The output is as follows.
assets/css/site.css
Relativize only subpaths with --relative-base
It can output as a relative path only when the target is under the base directory, and keep it as an absolute path if it is outside.
realpath --relative-base=/srv/www /srv/www/index.html /var/log/syslog
The first path will be a relative path, and the second path will be output as an absolute path because it is outside the base.
Difference between readlink -f and realpath
| Comparison items | realpath |
readlink -f |
|---|---|---|
| Main Purpose | Normalization of file names and conversion to relative paths | Extended normalization function in symbolic link target output |
| Relative output | --relative-to and --relative-base support |
Generally outputs absolute canonical paths |
| Recommended usage | For path canonicalization, the GNU documentation recommends realpath |
The primary purpose is to check the target string stored in a link |
| Portability | You need to check the differences between options and default existence conditions | -f cannot be assumed to be the same across all Unix implementations |
Using in shell scripts
Recording the actual path of a configuration file
config=$(realpath -e -- "$1") || {
printf '%s\n' 'Cannot verify the configuration file path.' >&2
exit 1
}
printf 'Configuration file: %s\n' "$config"
Use -e to check that all components exist, but there is no guarantee that the file will remain unchanged until it is used later.
Safely separating multiple filenames
-z or --zero outputs a NUL character at the end of each result instead of a newline.
realpath -z -- file1 "file with space"
It is useful in automation where filenames may include newlines, and the program receiving the results must also support NUL-delimited input.
Points to be careful about when performing path verification
Normalization and access permission are different
Just because a normalized path appears under a specific directory does not automatically grant read or write permissions. You must separately check ownership, permissions, ACLs, and security policies.
The target can change between checking and using it
If a symbolic link or directory changes between checking with realpath and opening the file, a different target may be used. At security boundaries, do not rely solely on simple string comparisons, and use safe file opening methods and permission separation provided by the operating system.
Be careful with prefix string comparisons
/srv/www-safe also starts with /srv/www in the string. When checking for inclusion of a base path, consider directory boundaries, as path normalization alone does not create a secure sandbox.
Summary of major options
| Option | Description |
|---|---|
-E, --canonicalize |
Normalize paths even if the last component is missing. |
-e, --canonicalize-existing |
All components must actually exist for success. |
-m, --canonicalize-missing |
Treat non-existent components as directories. |
-L, --logical |
Interpret symbolic links after logically processing ... |
-P, --physical |
It is a physical mode that resolves symbolic links first and is the default for GNU. |
-s, --no-symlinks |
It cleans up the path string without resolving symbolic links. |
--relative-to=directory |
Prints relative paths based on the specified directory. |
--relative-base=directory |
Only prints paths under the base as relative paths. |
-q, --quiet |
Suppresses diagnostic messages about the specified path. |
-z, --zero |
Separates results with NUL characters. |
FAQ
Can realpath be used on files that do not exist?
In GNU default behavior or with -E, it can handle the case where the last component does not exist. If intermediate components may be missing, use -m; to require all components to exist, use -e.
Does realpath always resolve symbolic links?
In default physical mode, it resolves symbolic links. To normalize the path string without following links, use -s or --no-symlinks.
What is the difference between pwd -P and realpath.?
Both can show the physical absolute path of the current location. pwd -P is specialized for the current working directory, while realpath provides options for multiple arbitrary paths, existence conditions, and relative path output.
Can checking only the realpath result prevent path traversal attacks?
No. The path can change between the check and file usage, and permission issues are separate. At trust boundaries, you should use safe file-opening APIs together with permission separation and directory boundary checks.









