opscape

Files and directories

readlink

Print where a symbolic link points, or with -f the fully resolved path of any file.

readlink [OPTION...] FILE...

7 of 7 examples run in Debian 13.7 on 2026-10-31 · coreutils 9.7-3 · manual: readlink(1)

Without options, readlink prints the contents of a symbolic link: the target text exactly as it was stored by ln -s, which may be relative and may not even exist. If the file is not a symlink, it prints nothing and fails.

With -f, -e or -m it canonicalizes instead: follows every link in every component and prints an absolute path, the same job as realpath. readlink -f is the older, more widely known spelling, so you will see it in many scripts.

Examples

Where does a symlink point

readlink link-to-notes
explain
output
notes.txt

The stored target is printed as-is: notes.txt, relative to the link's directory.

One level versus fully resolved

Setup run before this example
ln -s link-to-notes second-link
readlink second-link
readlink -f second-link
output
link-to-notes
/home/dev/demo/notes.txt

second-link points to link-to-notes, which points to notes.txt. Plain readlink shows one hop; -f follows the whole chain and prints an absolute path.

Canonical path of any file

readlink -f src/../data/./users.csv
explain
output
/home/dev/demo/data/users.csv

-f works on regular files too: .. and . are resolved and the result is absolute.

Broken links

Setup run before this example
ln -s old-config.json config.json
readlink config.json
readlink -f config.json
readlink -e config.json
outputexit 1
old-config.json
/home/dev/demo/old-config.json

Plain readlink still shows the target text. -f prints the path the target would have, since only the last component may be missing. -e requires the target to exist, prints nothing and fails.

Find what a process has open

readlink /proc/$$/exe
readlink /proc/$$/cwd
output
/usr/bin/bash
/home/dev/demo

On Linux, /proc/PID/exe and /proc/PID/cwd are symlinks to the program a process is running and its working directory. $$ is this shell's process ID.

Find the real program behind a command

readlink -f "$(command -v awk)"
explain
output
/usr/bin/gawk

/usr/bin/awk is a symlink through the Debian alternatives system. readlink -f follows the chain to the program that actually runs, gawk.

Common pitfalls

  • readlink file on a non-link prints nothing; a script that uses $(readlink "$f") as a path will get an empty string. Use readlink -f or realpath when you want a path either way.

  • The target text from plain readlink is relative to the link's directory, not to your current directory.

GNU vs BSD and macOS

The examples above ran the GNU/Linux version. These are the differences that matter on macOS and the BSDs (written from their documentation, not run here).

  • readlink -f works on GNU and on macOS 12.3 and later; older macOS lacks it. -e and -m are GNU-only.

Options worth knowing

A selection, described in our own words. For the full list, see readlink(1) or readlink --help.

OptionWhat it does
-f, --canonicalizeResolve all links; every component but the last must exist.
-e, --canonicalize-existingResolve all links; every component must exist.
-m, --canonicalize-missingResolve all links; no component needs to exist.
-n, --no-newlineDo not print the trailing newline.
-q, --quietSuppress most error messages.
-s, --silentSame as -q.
-v, --verboseReport errors.
-z, --zeroEnd each output line with a NUL byte.

Related