Руководства

Символическая ссылка в Linux: как создать симлинк командой ln -s, исправить и удалить

Симлинк (символическая ссылка) в Linux указывает на другой путь. Как создать его через ln -s, сменить цель с -sfn, найти битые ссылки и безопасно удалить.

Опубликовано ~7 мин чтения
На этой странице

Коротко: символическая ссылка (симлинк, символьная ссылка) в Linux — это маленький файл, который указывает на другой путь. Создаётся она командой ln -s ЦЕЛЬ ИМЯ_ССЫЛКИ: сначала существующий файл или каталог, затем новая ссылка, в том же порядке, что и у cp. ls -l показывает, куда ведёт ссылка, а rm ИМЯ_ССЫЛКИ удаляет саму ссылку и не трогает цель.

любой Linux
ln -s /srv/app/releases/v2 /srv/app/current   # ссылка на каталог
ln -s ../shared/config.yml config.yml           # относительная ссылка на файл
ln -sfn releases/v3 current                     # перенаправить существующую ссылку на каталог
ls -l current                                   # current -> releases/v3
rm current                                      # удалить ссылку, а не цель

Весь вывод на этой странице получен в Debian 12 с GNU coreutils 9.1 и findutils 4.9.0 во временном каталоге 21 октября 2026 года; абсолютные пути в выводе сокращены до /srv/app и /etc/nginx. Раздел про Windows написан по справке Microsoft по команде mklink и не запускался. В Ubuntu, Rocky Linux и AlmaLinux тот же GNU ln.

Что такое символическая ссылка

Символическая ссылка — это файл, всё содержимое которого составляет путь. Когда программа открывает ссылку, ядро идёт по этому пути и открывает цель, поэтому редакторы, веб-серверы и скрипты работают со ссылкой так, будто это настоящий файл или каталог. В выводе ls -l она начинается с буквы l и показывает цель после стрелки:

Пример вывода
$ ln -sv releases/v2 app/current
'app/current' -> 'releases/v2'
$ ls -l app/current
lrwxrwxrwx 1 root root 11 Oct 21 19:45 app/current -> releases/v2

Размер 11 — это длина текста releases/v2: ничего, кроме этой строки, ссылка не хранит. Симлинк похож на ярлык Windows, но с одним важным отличием: ярлык — это файл, который понимает только оболочка Windows, а символическую ссылку разрешает ядро, и работает она для любой программы.

Как создать символическую ссылку в Linux

ln -s принимает сначала цель, затем имя новой ссылки. Если указать только цель или вторым аргументом назвать существующий каталог, ссылка появится там под именем самой цели:

любой Linux
ln -s /etc/hostname                    # создаёт ./hostname -> /etc/hostname
ln -s /opt/tool/bin/tool /usr/local/bin/ # создаёт /usr/local/bin/tool
ln -s -t /usr/local/bin /opt/tool/bin/*  # по ссылке на каждый файл, каталог назначения первым

Цель не обязана существовать. ln всё равно создаст ссылку и ни о чём не предупредит: это удобно для ссылки, которую вы заполните позже, и это же классический способ получить битую ссылку из-за опечатки. Вторая частая ошибка — перепутанные аргументы: ln -s newlink real при существующем real завершается ошибкой failed to create symbolic link 'real': File exists, потому что ln пытается создать ссылку под именем вашего существующего файла.

Жёсткая ссылка и символическая: в чём разница

Без -s команда ln создаёт жёсткую ссылку: второе имя того же файла, а не указатель на путь. Оба имени делят один inode, и данные живут, пока не удалено последнее имя:

Пример вывода
$ ln -v orig.txt hard.txt
'hard.txt' => 'orig.txt'
$ ls -li orig.txt hard.txt
3542701 -rw-r--r-- 2 root root 5 Oct 21 19:45 hard.txt
3542701 -rw-r--r-- 2 root root 5 Oct 21 19:45 orig.txt
$ rm orig.txt; cat hard.txt
data
Символическая (ln -s)Жёсткая (ln)
Что этоМаленький файл, в котором записан путьЕщё одно имя того же inode
Цель удаленаСсылка ломается (становится битой)Данные остаются, второе имя работает
КаталогиДаНет: hard link not allowed for directory
Между файловыми системамиДаНет: Invalid cross-device link
В выводе ls -ll в начале, -> цельВыглядит как обычный файл, счётчик ссылок больше 1
Типичное применениеТекущий релиз, sites-enabled, программы в /usr/local/binСнимки бэкапов (rsync --link-dest), дедупликация

Почти для всего на сервере нужен -s. Жёсткие ссылки встречаются в основном в инструментах резервного копирования, например в схеме со снимками из руководства по rsync.

Относительная или абсолютная цель?

Относительная цель отсчитывается от каталога, в котором лежит ссылка, а не от каталога, в котором вы были, когда набирали команду. Именно эта ошибка стоит за большинством битых ссылок:

Пример вывода
$ ln -s notes.txt conf/notes        # ищет conf/notes.txt
$ cat conf/notes
cat: conf/notes: No such file or directory
$ ln -sr notes.txt conf/notes       # -r сам вычисляет относительный путь
'conf/notes' -> '../notes.txt'
Относительная (../shared/x)Абсолютная (/srv/app/shared/x)
Переживает перенос всего дереваДаНет
Переживает перенос одной ссылкиНет: в проверке рабочая ссылка, перенесённая на каталог ниже, дала No such file or directoryДа: абсолютная ссылка, перенесённая так же, продолжила работать
Работает в контейнере или chroot, где дерево смонтировано по другому путиДаТолько если путь там такой же
Легко читатьХужеЛучше

Простое правило: относительные ссылки — внутри одного проекта или дерева релизов, абсолютные — из системных мест вроде /usr/local/bin или /etc/nginx/sites-enabled.

Как заменить ссылку: -f и -n

ln отказывается перезаписывать существующее имя. Ключ -f сначала удаляет старое, и для ссылки на файл этого достаточно:

Пример вывода
$ ln -s target.txt name
ln: failed to create symbolic link 'name': File exists
$ ln -sfv target.txt name
'name' -> 'target.txt'

Со ссылкой на каталог один -f делает не то: ln проходит по существующей ссылке внутрь каталога и создаёт новую ссылку уже там. -n велит ln считать существующую ссылку обычным файлом, поэтому ссылки на каталоги всегда перенаправляйте через -sfn:

Пример вывода
$ ln -sfv releases/v3 app/current
'app/current/v3' -> 'releases/v3'          # неверно: новая ссылка внутри releases/v2
$ ln -sfnv releases/v3 app/current
'app/current' -> 'releases/v3'             # верно

Если при переключении релиза ни один запрос не должен застать ссылку отсутствующей, создайте новую ссылку под временным именем и переименуйте её поверх старой командой mv -T current.new current: rename() заменяет имя атомарно.

Пример вывода
$ readlink app/current
releases/v3
$ readlink -f app/current
/srv/app/releases/v3
$ realpath app/current
/srv/app/releases/v3

Простой readlink печатает текст, записанный в ссылке, и раскрывает только один уровень. readlink -f и realpath проходят по всей цепочке ссылок и печатают итоговый абсолютный путь. Разница между вариантами видна на битых ссылках: для ссылки на несуществующий файл readlink -f и realpath всё равно напечатали предполагаемый путь с кодом возврата 0, а readlink -e не напечатал ничего и вернул 1, поэтому в скрипте проверять нужно именно им. pwd -P делает то же для текущего каталога; к чему это приводит, показано в руководстве по pwd (англ.).

Как найти и исправить битые симлинки

Пример вывода
$ ls -l broken
lrwxrwxrwx 1 root root 11 Oct 21 19:45 broken -> missing.txt
$ cat broken
cat: broken: No such file or directory

Ошибка называет саму ссылку, а она-то существует, поэтому поначалу это сбивает с толку. find -type l выводит все ссылки, а -xtype l — только те, чья цель отсутствует:

любой Linux
find /etc /usr/local -xtype l                 # список битых ссылок
find ./etc -xtype l -print -delete            # удалить их, сначала прочитав список

В проверке -xtype l вывел две битые ссылки и пропустил рабочую. Ссылка, которая указывает сама на себя, напрямую или по кругу, ломается иначе: cat a ответил Too many levels of symbolic links. Подробнее об этих проверках — в руководстве по find (англ.).

Как удалить симлинк: rm или unlink, без слеша в конце

rm current или unlink current удаляет ссылку и оставляет цель в покое. Проблемы начинаются со слеша в конце, который автодополнение оболочки добавляет к ссылке на каталог:

Пример вывода
$ rm current/
rm: cannot remove 'current/': Is a directory
$ unlink current/
unlink: cannot unlink 'current/': Not a directory
$ rmdir current
rmdir: failed to remove 'current': Not a directory
$ rm -v current
removed 'current'

Те же ошибки в русской локали

Если на сервере включена русская локаль, ln, rm и cat пишут те же ошибки по-русски, и искать их приходится уже в таком виде. Ниже — вывод тех же команд в Debian 12 (GNU coreutils 9.1) с переменными LC_ALL=C.UTF-8 и LANGUAGE=ru; в первом столбце тот же текст в английской локали:

Английская локальРусская локальЧто значит
ln: failed to create symbolic link 'name': File existsln: не удалось создать символьную ссылку 'name': Файл существуетИмя уже занято: нужен -f (для каталога -sfn), или перепутаны аргументы
cat: broken: No such file or directorycat: broken: Нет такого файла или каталогаЦели ссылки нет: ссылка битая
cat: a1: Too many levels of symbolic linkscat: a1: Слишком много уровней символьных ссылокСсылки указывают друг на друга по кругу
ln: dd: hard link not allowed for directoryln: dd: не допускается создавать жёсткие ссылки на каталогиДля каталога нужен ln -s
rm: cannot remove 'current/': Is a directoryrm: невозможно удалить 'current/': Это каталогУберите слеш в конце: rm current
rmdir: failed to remove 'current': Not a directoryrmdir: не удалось удалить 'current': Это не каталогЭто ссылка, а не каталог: rm current

Отсюда и разнобой в названиях: в переводе GNU coreutils это «символьная ссылка», в документации и статьях чаще пишут «символическая», а в разговоре говорят просто «симлинк». Все три слова означают одно и то же.

Права, владелец и копирование

  • Права: у симлинка всегда lrwxrwxrwx, и Linux их не учитывает. Значение имеют права цели. chmod 600 slink поменял права цели на -rw------- и не тронул ссылку; подробнее — в руководстве по chmod (англ.).
  • Владелец: chown тоже действует на цель; chown -h меняет владельца самой ссылки.
  • Копирование: простой cp slink copy скопировал содержимое цели в обычный файл; cp -P (и cp -a) скопировал ссылку как ссылку. rsync -a и tar тоже сохраняют ссылки ссылками.

Симлинки на сервере: sites-enabled в nginx и релизы

В Debian и Ubuntu файл nginx.conf подключает все файлы из /etc/nginx/sites-enabled, а не из sites-available. Сайт включают, создав ссылку на его файл из sites-available, а выключают, удалив ссылку:

Debian · Ubuntu
sudo ln -s /etc/nginx/sites-available/example.com /etc/nginx/sites-enabled/
sudo nginx -t && sudo systemctl reload nginx

# снова выключить сайт: удалить ссылку, но никогда не файл в sites-available
sudo rm /etc/nginx/sites-enabled/example.com
sudo nginx -t && sudo systemctl reload nginx
Пример вывода
$ ls -l /etc/nginx/sites-enabled
lrwxrwxrwx 1 root root 38 Oct 21 19:46 example.com -> /etc/nginx/sites-available/example.com

Здесь берите абсолютный путь. ln -s sites-available/example.com sites-enabled/, набранная в /etc/nginx, создаёт битую ссылку: её относительная цель отсчитывается от sites-enabled, и ссылка указывает на sites-enabled/sites-available/example.com. Полная настройка сайта описана в руководстве по reverse proxy на nginx (англ.). На той же схеме построены деплои без простоя: каждый релиз лежит в своём каталоге, а current указывает на рабочий, так что откат — это один ln -sfn обратно на предыдущий релиз.

Символические ссылки в Windows: mklink

В Windows тоже есть симлинки, их создаёт команда mklink в командной строке. По справке Microsoft порядок аргументов обратный по сравнению с Linux: сначала новая ссылка, затем цель.

cmd (от имени администратора)
rem символическая ссылка на файл
mklink C:\links\app.conf C:\apps\app\app.conf
rem символическая ссылка на каталог
mklink /D C:\www\current C:\www\releases\v2
rem соединение каталогов (junction)
mklink /J C:\data D:\data
rem жёсткая ссылка
mklink /H C:\links\hard.txt C:\files\orig.txt

Для создания символических ссылок по умолчанию нужны права администратора, поэтому открывайте командную строку через «Запуск от имени администратора». mklink — встроенная команда cmd, а не отдельная программа, поэтому в PowerShell используется своя команда:

PowerShell (от имени администратора)
New-Item -ItemType SymbolicLink -Path C:\www\current -Target C:\www\releases\v2

На Windows VPS соединения каталогов (/J) — привычный способ перенести папку с данными на другой диск или раздел так, чтобы программы продолжали работать по старому пути: они связывают только папки на локальных томах, а для их создания права администратора не нужны.

Частые вопросы

Что такое символическая ссылка (симлинк) в Linux?

Символическая ссылка, она же симлинк, символьная или мягкая ссылка, — это маленький файл, в котором записан путь к другому файлу или каталогу. Когда программа открывает ссылку, ядро открывает цель. Если цель удалить или переместить, ссылка становится битой и никуда не ведёт. Создаётся она командой ln -s ЦЕЛЬ ИМЯ_ССЫЛКИ.

Чем жёсткая ссылка отличается от символической?

Символическая ссылка хранит путь: она может указывать на каталоги и на другие файловые системы и ломается, если цель удалить. Жёсткая ссылка — второе имя тех же данных: данные живут, пока существует хотя бы одно имя, но жёсткие ссылки нельзя создавать на каталоги и между файловыми системами.

Как удалить симлинк, не удалив цель?

Выполните rm имя_ссылки или unlink имя_ссылки без слеша в конце. Со слешем rm считает имя каталогом, на который указывает ссылка: rm -rf имя_ссылки/ удаляет содержимое каталога-цели, а саму ссылку оставляет на месте.

Читайте также

Все статьи раздела