A
cd ..
Tools

Symlink & Hardlink Files

Create and manage symbolic and hard links with ln command.

2025-11-27
ln, symlink, hardlink

Symbolic link (symlink)

ln -s /path/to/original /path/to/link
ln -s /etc/nginx/nginx.conf ~/nginx.conf

Hard link

ln /path/to/original /path/to/link
ln /var/log/app.log ~/app.log

Differences

Symbolic link:

  • Points to path (string)
  • Can link directories
  • Can cross filesystems
  • Breaks if original is moved/deleted
  • Shows as link in ls -l

Hard link:

  • Points to inode
  • Cannot link directories
  • Must be same filesystem
  • Survives original deletion
  • Indistinguishable from original

Create symlink to directory

ln -s /var/www/html ~/www
ln -s ~/Documents/project ~/proj

Force overwrite

ln -sf /new/target existing-link

Relative symlink

# Absolute
ln -s /absolute/path/file link

# Relative  
cd /path/to
ln -s ../another/file link

List symlinks

ls -l | grep '^l'
find . -type l

Check what symlink points to

ls -l link
readlink link
readlink -f link  # Canonical path

Find broken symlinks

find .  -xtype l
find . -type l ! -exec test -e {} \; -print

Remove symlink

rm link
unlink link

# Don't use rm -r on symlink to directory!

Count hard links

ls -l file  # Number after permissions
stat file | grep Links

Find all hard links to file

find / -samefile /path/to/file
find / -inum $(stat -c %i file)

Common use cases

Config files

# Link config to home
ln -s /etc/nginx/nginx.conf ~/.config/nginx.conf

# Version control config
ln -s ~/dotfiles/.vimrc ~/.vimrc

Executables

# Make command available
sudo ln -s /opt/app/bin/app /usr/local/bin/app

Web directories

# Apache/Nginx document root
sudo ln -s /home/user/project /var/www/html/project

Shared libraries

sudo ln -s /usr/lib/libfoo.so.1.2.3 /usr/lib/libfoo.so.1

Multiple links

# Create links in target directory
ln -st /target/dir file1 file2 file3

Backup before overwrite

ln -sb /new/target existing-link
# Creates existing-link~ backup

Interactive mode

ln -si source target
# Prompts before overwrite

Verbose output

ln -sv source target

Check if path is symlink

# In script
if [ -L "$path" ]; then
    echo "Is a symlink"
fi

Update all symlinks in directory

find . -type l -exec sh -c '
    target=$(readlink "$1")
    new_target=$(echo "$target" | sed "s|old|new|")
    ln -sf "$new_target" "$1"
' _ {} \;

Troubleshooting

Permission denied

#  Check  original file permissions
ls -l /path/to/original

# Check parent directory permissions
ls -ld /path/to/

Too many levels of symbolic links

# Circular symlink
ls -l link
readlink -f link  # Shows error

Cross-device link (trying hard link across filesystems)

# Use symlink instead
ln -s /mnt/otherdisk/file ~/link

Was this useful?

Share with your team

Browse More