VMware ESXi and vSphere Cluster Management

Linux Links: Hard Links, Symbolic Links, and Inodes

Learn how Linux hard links and symbolic links work, how inodes and directory entries relate, and how to create, inspect, replace, and safely remove links with ln.

A Linux link is a filesystem reference that gives an object an additional accessible pathname. One filesystem object can therefore be reached through more than one name. Links are useful for convenient alternate locations, compatibility with software that expects a particular path, alternate command names, shared access to one file, and version-independent references such as current pointing to the active release.

A copied file is different: copying creates a separate file object with separate contents. Editing one copy does not edit the other. A link creates another reference to an existing object, although hard links and symbolic links implement that reference differently. A Windows shortcut is a useful high-level analogy for a symbolic link, but a Linux hard link is not a shortcut: it is another directory entry for the same underlying file object.

Files, directory entries, and inodes

An inode is a filesystem metadata record associated with a file object. It commonly stores ownership, permissions, timestamps, file size, and references to the data blocks containing the file's contents. The inode does not normally store the filename.

A filename is a directory entry: a mapping from a name in a directory to an inode number. This distinction explains hard links. Two different names can be two directory entries that map to the same inode.

The inode's link count is the number of hard-link directory entries referring to it. Storage is released only after the final hard-link reference is removed and no process still has the file open. Consequently, removing a filename does not always immediately free the file's disk space.

Hard links

A hard link is another directory entry for the same inode and underlying file data. Hard-linked names normally show the same inode number and the same link count. They are equal references to the file object; there is no special original name that owns the data.

printf 'shared content\n' > report.txt
ln report.txt report-current.txt
ls -li report.txt report-current.txt
printf 'updated content\n' >> report-current.txt
cat report.txt

The two ls -li entries should have the same inode number. The link count should increase when report-current.txt is created. Text appended through that name is visible through report.txt, because both names reach the same data.

Removing one hard-link name removes one directory entry, not the shared file data:

rm report-current.txt
ls -li report.txt
cat report.txt

The remaining name still works and its link count decreases. Hard links ordinarily cannot cross a filesystem boundary, meaning independently mounted filesystems. They are also generally not permitted for directories because directory hard links could create unsafe filesystem cycles. Permissions and ownership are inode-level properties, so hard-linked names cannot have independent permissions or ownership.

Symbolic links

A symbolic link, also called a symlink or soft link, is a special filesystem object containing a reference path to another object. The referenced file or directory is the symlink's target. A symlink has its own inode and its own directory entry, unlike a hard link.

Symlinks can refer to files or directories and can cross filesystem boundaries. They can store either an absolute path, which begins at the filesystem root, or a relative path, which is interpreted from the directory containing the symlink. The shell's current working directory at creation time is not the context used later to resolve a relative target.

ln -s /home/user/docs/report.txt /home/user/bin/latest-report
ls -l /home/user/bin/latest-report
readlink /home/user/bin/latest-report

The long listing identifies the entry as a symbolic link and displays its stored target. The symlink has a different inode from /home/user/docs/report.txt.

Relative links can make a complete directory tree portable:

mkdir -p project/releases project/current
printf 'v1\n' > project/releases/app.conf
ln -s ../releases/app.conf project/current/app.conf
cat project/current/app.conf

Here, ../releases/app.conf is resolved relative to project/current, the directory containing the symlink. If the complete project tree is moved together, that relationship can remain valid.

A dangling symlink, or broken symlink, is a symlink whose target path no longer resolves. Moving or removing the target commonly causes this condition. The symlink object still exists, but opening it fails.

ln -s missing-file.txt shortcut.txt
ls -l shortcut.txt
readlink -f shortcut.txt

readlink -f attempts to resolve the complete chain to a canonical existing path where supported. For a missing target, resolution fails or produces no usable path, depending on the platform.

Hard links and symbolic links compared

What it references — Hard link: the same inode and data. Symbolic link: a pathname stored in a separate link object.

Inode relationship — Hard link: names share an inode. Symbolic link: the link has its own inode.

Can cross filesystems — Hard link: ordinarily no. Symbolic link: yes.

Can link to directories — Hard link: generally no. Symbolic link: yes.

When the target pathname is removed — Hard link: other names still access the inode. Symbolic link: the link becomes dangling if its target path disappears.

When one link name is deleted — Hard link: one directory entry disappears and the link count decreases. Symbolic link: only the symlink object disappears.

Permissions and ownership — Hard link: names share inode-level properties. Symbolic link: the target's properties control ordinary access to the target.

Appearance in ls -l — Hard link: appears as an ordinary file. Symbolic link: has link type information and usually displays -> followed by its target.

Typical uses — Hard link: shared file data and alternate names on one filesystem. Symbolic link: alternate directories, cross-filesystem references, command aliases, release pointers, and paths that may refer to directories.

Creating links with ln

The basic form is ln SOURCE DESTINATION. Without an option requesting symbolic-link mode, ln creates a hard link:

ln report.txt report-copy-name

To create a symlink, use -s:

ln -s TARGET LINK_NAME
ln -sv /usr/bin/example-tool ~/bin/example-tool-alt

The second command is useful for an alternate command name, but use a harmless locally installed command or a controlled test script rather than assuming a particular system binary exists. The target and its permissions must be valid when the alternate name is used.

If the destination is an existing directory, ln normally creates the link inside that directory:

mkdir -p ~/bin
ln -s /home/user/docs/report.txt ~/bin/latest-report

Always check whether a destination already exists. Depending on the command and options, ln can refuse, replace, or create an entry inside a destination directory. Accidental replacement of a production path can be disruptive.

ln — Create a hard link by default: ln SOURCE DESTINATION.

ln -s — Create a symbolic link: ln -s TARGET LINK_NAME.

ln -v — Report the operation: ln -sv TARGET LINK_NAME.

ln -f — Force removal of an existing destination before creating the link; use cautiously because it can overwrite a name.

ln -n — Treat an existing symlink destination as a normal file rather than following it as a directory in implementations that support this option.

ln -sfn — Commonly used to replace an existing symlink-like destination without traversing a destination directory. Verify the destination first; option behavior and replacement details can vary, and careless use can remove the wrong name.

ls -l — Show symlink type and its recorded target.

ls -li — Show inode numbers and link counts in addition to a long listing.

stat — Inspect detailed metadata, including file type, inode number, and hard-link count.

readlink — Print the direct target stored in a symlink.

readlink -f — Resolve a symlink chain to a canonical existing path where supported.

Inspecting and verifying links

Use ls -li to compare hard-linked names:

ls -li report.txt report-current.txt
stat report.txt
stat report-current.txt

Matching inode numbers and matching link counts are strong evidence that the names are hard links to the same inode. Use ls -l to identify a symlink and show its direct target:

ls -l ~/bin/latest-report
readlink ~/bin/latest-report
readlink -f ~/bin/latest-report

Examining a symlink and following it are different operations. ls -l LINK and readlink LINK inspect the link object and its stored path. Commands such as stat LINK may follow the link depending on the platform and options, while stat -L LINK explicitly follows it on common Linux implementations. Consult the local command's manual when the distinction matters.

Link lifecycle outcomes

Edit through an alternate name — Hard link: changes the shared file. Symbolic link: changes the target if it resolves to a file.

Delete the alternate name — Hard link: removes one name; other names remain. Symbolic link: removes only the symlink.

Delete the original-looking name — Hard link: data remains through other hard links. Symbolic link: target remains; only the symlink is removed.

Move the target file — Hard link: the other hard-link name still works because it reaches the inode. Symbolic link: the link usually becomes dangling because its stored path did not change.

Move the symlink — The stored target text does not automatically change. An absolute target may continue working; a relative target may resolve differently because its parent directory changed.

Move an enclosing directory containing a relative symlink — The link can continue working if the target and symlink retain the same relative relationship inside the moved tree.

Safe removal and replacement

Use rm LINK_NAME to remove a hard-link directory entry or the symlink object named by that path:

rm report-current.txt
rm ~/bin/latest-report

rm on a symlink removes the symlink, not its target. Removing one hard-link name leaves the shared file accessible through remaining names. Before deleting or replacing a production path, inspect it with ls -l, readlink, or stat.

Be especially careful with a symlink to a directory: avoid adding a trailing slash when removing the symlink itself. For example, prefer rm link-to-directory, not rm link-to-directory/. A trailing slash can cause a command to treat the path as a directory target, and behavior can differ between tools and systems.

Troubleshooting

A symlink is listed but cannot be opened

  • Inspect the stored path with readlink LINK and the long listing with ls -l LINK.
  • Try readlink -f LINK to test canonical resolution.
  • The target may have been deleted or renamed, a relative target may have been calculated from the wrong location, or an absolute target may not exist on this system.
  • Directory traversal permissions can also block access. Check components with namei -l PATH or ls -ld on each directory.
  • Recreate the symlink with the correct target, restore the target, or use a relative target when a directory tree is intended to move together.

A new link has a different inode from the source

  • You may have used ln -s, which creates a separate symlink inode.
  • The source may have been copied instead of linked, or the wrong paths may have been compared.
  • Run ls -li on both paths and ls -l to see whether one path is a symlink.
  • Use ln without -s when a hard link is required and both paths are on the same filesystem.

Hard-link creation fails with a cross-device error

The source and destination are on different mounted filesystems. Compare device information with df or stat. Use a symbolic link instead, or place both names on the same filesystem.

Hard-link creation for a directory is rejected

Normal Linux operation generally prevents users from creating directory hard links to protect filesystem structure. Use a symbolic link for an alternate directory pathname.

Removing a file did not free disk space

Other hard links may still reference the inode. Check the link count with stat or ls -li. A running process may also still have the unlinked file open; use a suitable local tool such as lsof when available. Remove remaining unneeded hard-link names and ensure relevant processes close the file.

A relative symlink fails after reorganization

Its relative relationship to the target changed. Recalculate the target relative to the symlink's parent directory, or deliberately use an absolute path when portability is not required.

Exam-relevant notes

  • A hard link is another directory entry for the same inode; a symlink is a separate object containing a pathname.
  • Matching inode numbers identify hard-linked names. Symlinks normally have different inode numbers from their targets.
  • Hard links ordinarily stay within one filesystem and generally cannot target directories.
  • A relative symlink target is interpreted relative to the directory containing the symlink.
  • Removing a symlink does not remove its target. Removing one hard-link name does not remove the inode while other links or open file descriptors remain.
  • Use ln for hard links, ln -s for symbolic links, ls -li and stat for inode and link-count checks, and readlink for symlink targets.