How to Create Symlinks in Linux with ln

By 

Updated on

11 min read

ln command in Linux for creating symbolic links

When a tool, configuration file, or release directory moves, you do not always want to chase every script and shortcut that points at it. A symbolic link gives you a stable name to keep pointing at the right target, and the ln command is what creates those links on Linux.

This guide explains how to create symlinks in Linux with the ln command, how to overwrite or update them safely, and how to clean up broken links.

How to Use the ln Command

ln is a command-line utility for creating links between files. By default, the ln command creates hard links. To create a symbolic link, use the -s (--symbolic) option.

The ln command syntax for creating symbolic links is as follows:

txt
ln -s [OPTIONS] FILE LINK
  • If both the FILE and LINK are given, ln will create a link from the file specified as the first argument (FILE) to the file specified as the second argument (LINK).
  • If only one file is given as an argument or the second argument is a dot (.), ln will create a link to that file in the current working directory . The symlink will have the same name as the file it points to.

By default, on success, ln does not produce any output and returns zero.

To create a symbolic link to a given file, open your terminal and type:

Terminal
ln -s source_file symbolic_link

Replace source_file with the name of the existing file you are linking to, and symbolic_link with the name you want the link to have. In the following example, we are creating a symbolic link named my_link.txt that points to a file named my_file.txt:

Terminal
ln -s my_file.txt my_link.txt

To verify that the symlink was successfully created, use the ls command:

Terminal
ls -l my_link.txt

The output will look something like this:

output
lrwxrwxrwx 1 linuxize users 11 Nov  2 23:03 my_link.txt -> my_file.txt

The l character is a file type flag that represents a symbolic link. The -> symbol shows the file the symlink points to.

Info
If you delete or move the target file, the symlink will be left dangling (broken) and should be removed.

The command for creating a symbolic link to a directory is the same as for creating a symbolic link to a file. Specify the directory name as the first parameter and the symlink as the second parameter.

For example, if you want to create a symbolic link from the /mnt/my_drive/movies directory to the ~/my_movies directory you would run:

Terminal
ln -s /mnt/my_drive/movies ~/my_movies

A symlink stores the path you typed, not the path it resolved to when you created it. That single detail explains most broken links. To follow the examples below, create a sample file and a directory for the links:

Terminal
touch my_file.txt
mkdir -p links

When you give ln a relative path, the link looks for that path starting from the directory the link lives in, which is not always the directory where you ran the command:

Terminal
ln -s my_file.txt links/broken_link.txt

The new link sits in links/, so it looks for my_file.txt inside links/, where nothing of that name exists. The listing shows the stored path and gives the problem away:

Terminal
ls -l links/broken_link.txt
output
lrwxrwxrwx 1 linuxize users 11 Jul 30 09:14 links/broken_link.txt -> my_file.txt

The output shows that the link stores my_file.txt, which resolves inside the links/ directory instead of the current directory.

An absolute path does not depend on the directory that contains the link. The following command uses $PWD to create a link to the sample file with its full path:

Terminal
ln -s "$PWD/my_file.txt" links/absolute_link.txt

When you use GNU Coreutils, ln can work out a relative path for you with the -r (--relative) option. It takes the target you name and rewrites it relative to the location of the link:

Terminal
ln -sr my_file.txt links/relative_link.txt

Verify the stored path with ls -l:

Terminal
ls -l links/relative_link.txt
output
lrwxrwxrwx 1 linuxize users 14 Jul 30 09:16 links/relative_link.txt -> ../my_file.txt

This time ln stored ../my_file.txt, which points back out of links/ to the real file. The -r option is a GNU extension and is not available in every ln implementation. When it is unavailable, specify the relative target yourself:

Terminal
ln -s ../my_file.txt links/portable_link.txt

Both forms keep working when you move the whole directory tree without changing the layout, which suits source checkouts, dotfiles, and anything you may relocate later. Save absolute paths for system locations such as /usr/local/bin that are not going to move.

Linux and UNIX systems have two kinds of links, and ln creates both:

  • Soft links. A symbolic link, also called a soft link, is a small file that holds the path to another file or directory. It is comparable to a shortcut in Windows, and it can point across partitions and filesystems or at a directory.
  • Hard links. A hard link is an additional name for an existing file. Two or more names share the same inode , so they refer to the same data on disk. One file can have many hard links, but they are for files only on most systems and cannot cross filesystems.

Everything up to this point used symbolic links, which is what most tasks call for. Hard links are the other half of what ln does.

Without the -s flag, ln creates a hard link instead of a symbolic one. A hard link points to the same inode as the original file, so both names refer to exactly the same data on disk.

To create a hard link, drop the -s:

Terminal
ln my_file.txt my_hardlink.txt

If you list the file with ls -li, both names share the same inode number:

Terminal
ls -li my_file.txt my_hardlink.txt
output
1234567 -rw-r--r-- 2 linuxize users 12 Apr 29 10:00 my_file.txt
1234567 -rw-r--r-- 2 linuxize users 12 Apr 29 10:00 my_hardlink.txt

The 2 in the link-count column shows that two names point to the same inode. Hard links cannot cross filesystems and, on most systems, cannot point to directories. Reach for symlinks when you need either of those. For a full breakdown of how the two link types differ, see hard links vs symbolic links .

If you attempt to create a symbolic link that already exists, the ln command will output an error message.

Terminal
ln -s my_file.txt my_link.txt
output
ln: failed to create symbolic link 'my_link.txt': File exists
Warning
The -f option can replace a regular destination file, not only a symlink. Run ls -l my_link.txt first and verify that it is the link you intend to replace.

After verifying the destination, use the -f (--force) option to replace it:

Terminal
ln -sf my_file.txt my_link.txt

If the existing link points to a directory, plain -f will not do what you expect. ln follows the symlink and creates the new link inside the target directory instead of replacing the link itself. To swap the link in place, add the -n (--no-dereference) flag:

Terminal
ln -sfn /opt/app/releases/2.1.0 /opt/app/current

This pattern is common in simple deployment scripts. /opt/app/current is a symlink that always points at the active release directory, and ln -sfn replaces it with a link to the new release.

For a stricter atomic swap, create a temporary symlink and move it over the existing link:

Terminal
ln -s /opt/app/releases/2.1.0 /opt/app/current.tmp
mv -Tf /opt/app/current.tmp /opt/app/current

mv -T treats the destination as a normal path instead of moving the temporary link into a directory. The final rename is atomic on the same filesystem.

To check whether a single file is a symlink, use ls -l. Symlinks show up with an l as the first character and an arrow pointing at the target:

Terminal
ls -l /usr/bin/python3
output
lrwxrwxrwx 1 root root 10 Mar 14 09:12 /usr/bin/python3 -> python3.12

To list every symlink under a directory, ask find for the file type l:

Terminal
find /etc -type l

To find broken symlinks (links whose target no longer exists), use find with -xtype l:

Terminal
find /etc -xtype l

-xtype l evaluates the type after dereferencing, so a symlink whose target is missing reports as a link rather than a regular file or directory.

When a symlink points to another symlink, or you want to know the absolute path it resolves to, ls -l only shows the immediate target. The readlink command gives you that one hop, and readlink -f walks the whole chain to the final canonical path.

Terminal
readlink /usr/bin/python3
output
python3.12
Terminal
readlink -f /usr/bin/python3
output
/usr/bin/python3.12

readlink -f is the form most scripts want, since it returns a path you can pass to other commands without worrying about how many indirection steps it took to get there.

The mode you see on a symlink (lrwxrwxrwx) is misleading. It always reads as 777 because Linux ignores the link’s own permissions and uses the target’s permissions for any read, write, or execute operation. Running chmod on a symlink follows the link and changes the target’s mode, not the link’s.

On Linux, you normally cannot change the symlink node permissions with GNU chmod. Change the permissions on the target file instead, and treat the symlink mode shown by ls -l as informational.

To delete/remove symbolic links , use either the unlink or rm command.

The syntax of the unlink is very simple:

Terminal
unlink symlink_to_remove

Removing a symbolic link using the rm command is the same as when removing a file:

Terminal
rm symlink_to_remove

No matter which command you use, when removing a symbolic link do not append the / trailing slash at the end of its name.

Quick Reference

For a printable quick reference, see the ln cheatsheet .

TaskCommand
Create a symlinkln -s source link_name
Create a symlink with a relative target (GNU ln)ln -sr source dir/link_name
Create a hard linkln source hardlink_name
Replace a verified symlinkln -sfn source link_name
Atomically swap a directory symlinkln -sfn /new/target /path/current
List symlinks in a directoryfind /path -type l
Find broken symlinksfind /path -xtype l
Resolve a symlink’s targetreadlink -f link_name
Remove a symlinkunlink link_name or rm link_name

Troubleshooting

File exists when creating a link
The destination path is already in use. Inspect it with ls -l. If it is a symlink you intend to replace, use ln -sfn new_target link_name. If it is a regular file or directory, move or remove it only after verifying that it is safe to do so.

Broken or dangling symlink
The target was renamed, moved, or deleted. It can also mean the link stores a relative path that does not resolve from the directory the link lives in. Run ls -l to see the stored path, then point the link at the new location with ln -sfn, rebuild it with GNU ln -sr, or delete it with unlink.

Too many levels of symbolic links
A symlink eventually points back at itself, forming a loop. readlink -f fails when it cannot resolve the chain and does not show each hop. Use readlink link_name to inspect the immediate target, repeat the command for each symlink in the chain, and replace or remove the link that closes the loop.

Permission denied when creating a link
You do not have write permission on the parent directory of the link path. Either run the command with sufficient privileges, or place the link somewhere you own.

chmod on a symlink does not change the link
On Linux, chmod follows the symlink and modifies the target. GNU chmod does not provide a portable way to change the symlink node permissions, and Linux ignores those permissions for normal access checks.

FAQ

What is the difference between ln -sf and ln -sfn?
ln -sf overwrites the destination, but if the destination is itself a symlink to a directory, ln follows that symlink and writes the new link inside the target directory. Adding -n tells ln not to dereference the destination, so the link itself is replaced. Use ln -sfn when the destination might already be a symlink to a directory. For deployment paths where readers may hit the link during the update, use the temporary symlink plus mv -T pattern shown above.

What is the difference between a hard link and a symbolic link?
A hard link is another name for the same inode, so both names refer to the same data on disk and share permissions and ownership. A symbolic link is a small file that stores the path to its target, can cross filesystems, and can point at directories. If the target of a symlink is removed, the symlink becomes broken; deleting one hard link still leaves the data accessible through the others.

Does sudo ln do anything different?
sudo only changes the user that runs the command. The link itself behaves the same way. Reach for sudo ln when you need to create a link inside a directory you do not own, such as /usr/local/bin.

How do I find every symlink in a directory?
Run find /path -type l to list them, or find /path -xtype l to list only the broken ones.

Can a symlink point to a file that does not exist yet?
Yes. ln -s does not check that the target exists at creation time. The link will resolve as broken until the target is created, which is sometimes useful when laying out a directory tree before populating it.

Conclusion

ln -s source link_name covers most day-to-day symlink work, but inspect an existing destination before replacing it and use ln -sfn when the link may point to a directory. For the full set of options, see the ln man page or type man ln in your terminal.

Linuxize Weekly Newsletter

A quick weekly roundup of new tutorials, news, and tips.

About the authors

Dejan Panovski

Dejan Panovski

Dejan Panovski is the founder of Linuxize, an RHCSA-certified Linux system administrator and DevOps engineer based in Skopje, Macedonia. Author of 800+ Linux tutorials with 20+ years of experience turning complex Linux tasks into clear, reliable guides.

View author page