Жёсткие и символические ссылки

Рейтинг: 61% · 6 голосов
Полный курс LPIC-1 (экзамены 101-500 и 102-500): архитектура, загрузка, пакеты, команды и текст, ФС и права, шелл-скрипты, пользователи, сервисы, сеть, безопасность. Debian и RHEL.
Ответить
Аватара пользователя
Sergey_Sysadmin
Сообщения: 134
Зарегистрирован: 11 май 2026, 05:31

Жёсткие и символические ссылки

Сообщение Sergey_Sysadmin »

Оглавление курса (41)
  1. Введение в LPIC-1 и как устроен путь администратора
  2. Железо, устройства и модули ядра [101.1]
  3. Загрузка системы: от BIOS до systemd [101.2]
  4. systemd, цели и уровни выполнения [101.3]
  5. План разметки диска и swap [102.1]
  6. Загрузчик GRUB 2 [102.2]
  7. Разделяемые библиотеки [102.3]
  8. Управление пакетами в Debian: dpkg и apt [102.4]
  9. Управление пакетами RPM, DNF и Zypper [102.5]
  10. Linux как гость виртуализации [102.6]
  11. Командная строка Bash [103.1]
  12. Обработка текста фильтрами [103.2]
  13. Базовое управление файлами [103.3]
  14. Потоки, конвейеры и перенаправление [103.4]
  15. Процессы: создание, мониторинг, сигналы [103.5]
  16. Приоритеты выполнения процессов [103.6]
  17. Регулярные выражения [103.7]
  18. Редактор vi и vim [103.8]
  19. Разделы и создание файловых систем [104.1]
  20. Целостность и обслуживание ФС [104.2]
  21. Монтирование файловых систем [104.3]
  22. Урок 21. Права доступа и владение: rwx, chmod, umask и специальные биты
  23. Жёсткие и символические ссылки (вы здесь)
  24. FHS и поиск файлов в системе [104.7]
  25. Окружение и кастомизация оболочки [105.1]
  26. Урок 25. Написание простых bash-скриптов [105.2]
  27. Графика, рабочие столы и доступность
  28. Учётные записи пользователей и групп
  29. Автоматизация задач: cron, at, таймеры [107.2]
  30. Локализация и интернационализация [107.3]
  31. Системное время и синхронизация [108.1]
  32. Системное логирование [108.2]
  33. Основы почтового агента (MTA) [108.3]
  34. Печать и CUPS [108.4]
  35. Основы интернет-протоколов [109.1]
  36. Постоянная конфигурация сети [109.2]
  37. Диагностика сети [109.3]
  38. DNS на стороне клиента [109.4]
  39. Задачи администрирования безопасности [110.1]
  40. Настройка безопасности хоста [110.2]
  41. Шифрование данных: SSH и GnuPG [110.3]
Урок 22. Жёсткие и символические ссылки [104.6]

Администратору постоянно нужно, чтобы один и тот же файл был доступен под несколькими именами или в нескольких местах: общий конфиг, текущая версия бинарника, файл лога, на который смотрит сразу пара демонов. Linux даёт для этого два разных механизма - жёсткие и символические ссылки. Они выглядят похоже, но работают совершенно по-разному, и путаница между ними приводит к битым путям и потерянным данным. В этом уроке разберём, что такое инод, чем жёсткая ссылка отличается от символической, какие у каждой ограничения и как читать вывод ls -li.

Изображение

Как это работает

В файловой системе само имя файла и сам файл - это разные сущности. Содержимое, права, владелец, размер, временные метки и адреса блоков с данными хранятся в структуре, которая называется инод (inode). У каждого инода есть номер, уникальный в пределах конкретной файловой системы. А вот имя файла живёт в каталоге: каталог - это просто таблица, которая сопоставляет человекочитаемые имена номерам инодов. Имени в самом иноде нет.

Из этого следует ключевая идея. Жёсткая ссылка (hard link) - это ещё одна запись в каталоге, указывающая на тот же самый инод. То есть это полноценное второе имя одного и того же файла, равноправное с первым. Нет никакого оригинала и копии - есть один инод и несколько имён. В иноде хранится счётчик ссылок (link count): сколько имён на него указывают. Файл физически удаляется и его блоки освобождаются только тогда, когда счётчик падает до нуля и при этом файл не открыт ни одним процессом. Команда rm на самом деле делает unlink - убирает одно имя и уменьшает счётчик.

Символическая ссылка (symlink, мягкая ссылка) устроена иначе. Это отдельный маленький файл со своим собственным инодом, внутри которого записан текстовый путь к цели. Когда вы обращаетесь к симлинку, ядро читает этот путь и перенаправляет вас по нему. Симлинк не знает и не интересуется номером инода цели - он хранит только строку пути. Поэтому симлинк гибкий: может указывать на другую файловую систему, на каталог, на ещё не существующий объект. И поэтому же он хрупкий: если цель переименовать, переместить или удалить, ссылка останется, но будет указывать в пустоту - это битая (dangling) ссылка.

Отсюда границы применимости. Жёсткая ссылка работает только в пределах одной файловой системы, потому что номера инодов уникальны лишь внутри неё - сослаться номером инода на файл с другого раздела невозможно. И жёсткие ссылки на каталоги обычно запрещены, чтобы не создавать циклы в дереве, которые сломали бы обход ФС. Симлинк свободен от обоих ограничений, но платит за это надёжностью.

Команды и примеры

Создание жёсткой ссылки - ln без ключей, сначала цель, потом новое имя:

Код: Выделить всё

echo "config v1" > /srv/app.conf
ln /srv/app.conf /srv/app.conf.bak
ls -li /srv/app.conf /srv/app.conf.bak
В выводе ls -li первая колонка - номер инода. У обоих имён он одинаковый, а в колонке счётчика ссылок (после прав доступа) стоит 2:

Код: Выделить всё

131074 -rw-r--r-- 2 root root 10 Jun 14 10:00 /srv/app.conf
131074 -rw-r--r-- 2 root root 10 Jun 14 10:00 /srv/app.conf.bak
Удаление одного имени не трогает данные - второе имя продолжает работать, счётчик становится 1.

Символическая ссылка - тот же ln с ключом -s:

Код: Выделить всё

ln -s /srv/app.conf /etc/app/current.conf
ls -li /etc/app/current.conf
Вывод покажет другой инод, тип l (буква l в начале строки прав) и стрелку на цель:

Код: Выделить всё

262150 lrwxrwxrwx 1 root root 13 Jun 14 10:05 /etc/app/current.conf -> /srv/app.conf
Права lrwxrwxrwx у симлинка декоративные - доступ определяется правами цели. Куда реально ведёт ссылка, удобно смотреть через readlink -f (резолвит всю цепочку до конечного файла) или namei -l, который раскладывает путь по компонентам и показывает каждый.

Поиск битых ссылок. Команда find одинакова в Debian/Ubuntu и RHEL/Fedora, отличий нет:

Код: Выделить всё

find /etc -xtype l
Ключ -xtype l в сочетании с поведением find по умолчанию находит симлинки, чья цель не существует. Альтернатива - find /etc -type l ! -exec test -e {} \; -print. Чтобы посмотреть метаданные именно ссылки, а не цели, используйте stat без разыменования:

Код: Выделить всё

stat current.conf      # покажет цель (разыменует)
stat -L current.conf   # явно по цели
ls -l current.conf     # покажет саму ссылку
Пакетных различий тут почти нет: ln, ls, find, stat, readlink входят в coreutils и util-linux и ведут себя одинаково и в Debian 13, и в Ubuntu 24.04, и в RHEL 10, и в Fedora 41+.

Частые грабли
  • Перепутать порядок аргументов ln. Память: как cp - сначала источник (цель ссылки), потом имя новой ссылки.
  • Создать симлинк с относительным путём из неправильного каталога. ln -s app.conf link сохранит ровно строку app.conf, и ссылка будет работать, только если рядом окажется файл с таким именем. Для стабильности используйте абсолютный путь или явно стройте относительный.
  • Пытаться сделать жёсткую ссылку между разделами и получить Invalid cross-device link. Проверьте через df, что цель и ссылка на одной ФС, иначе только -s.
  • Думать, что cp скопирует файл, а на деле скопировать симлинк. cp по умолчанию следует за ссылкой; чтобы сохранить саму ссылку, нужен cp -P или cp -a (для архивирования дерева).
  • Считать, что жёсткая ссылка экономит место на бэкапе между разделами. Hard link живёт в пределах одной ФС, для дедупликации файлов на одном носителе он подходит, но через границу раздела не работает.
  • Удалять цель симлинка, забыв про сам симлинк - он молча превращается в битый и продолжает торчать в каталоге.
Мини-лаба
  • Создайте файл: echo data > /tmp/orig.txt
  • Сделайте жёсткую ссылку /tmp/hard.txt и символическую /tmp/soft.txt на него.
  • Выполните ls -li для всех трёх и сравните номера инодов и счётчик ссылок.
  • Перезапишите содержимое через одно из имён (echo new > /tmp/hard.txt) и проверьте, что видно через orig.txt.
  • Удалите /tmp/orig.txt. Проверьте, что hard.txt всё ещё содержит данные, а soft.txt стал битым (cat /tmp/soft.txt).
  • Найдите битую ссылку командой find /tmp -xtype l.
  • Восстановите цель и убедитесь, что soft.txt снова работает.
Контрольные вопросы
  • Что физически хранится в иноде, а что - в записи каталога?
  • Почему нельзя создать жёсткую ссылку на файл, лежащий на другом смонтированном разделе?
  • Что произойдёт со счётчиком ссылок инода после удаления одного из его жёстких имён, и когда освободятся блоки данных?
  • Чем вывод ls -li для жёсткой и символической ссылки на один файл будет отличаться?
  • Какой командой найти все битые символические ссылки в дереве каталога?
  • Почему символическая ссылка может указывать на каталог и на другую ФС, а жёсткая - нет?
👍5 ❤️1 🔥 😄 🤔2
Аватара пользователя
oleg6
Сообщения: 2
Зарегистрирован: 01 июн 2026, 04:39

Re: Жёсткие и символические ссылки

Сообщение oleg6 »

А readlink -f и namei -l в чем разница на практике? оба же путь раскручивают
👍1 ❤️ 🔥 😄 🤔
Аватара пользователя
lifmabe
Сообщения: 1
Зарегистрирован: 13 май 2026, 16:18

Re: Жёсткие и символические ссылки

Сообщение lifmabe »

Поймал cross-device link когда делал ln с /home на отдельный /data раздел, df реально все объяснил - спасибо что предупредили
👍 ❤️ 🔥 😄 🤔
Ответить
← Предыдущая глава
Урок 21. Права доступа и владение: rwx, chmod, umask и специальные биты
Следующая глава →
FHS и поиск файлов в системе [104.7]

Все главы курса «LPIC-1: администратор Linux (101 + 102)»

Поделиться темой: ✈ Telegram VK

Вернуться в «LPIC-1: администратор Linux»

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и 1 гость