Порядок аргументов, на котором спотыкаются
Главная путаница с командой ln связана с порядком: первым аргументом идёт цель, то есть существующий файл или папка, а вторым — имя создаваемой ссылки. Запомнить помогает сравнение с cp: у обеих команд сначала «откуда», потом «куда». Запись ln -s ~/Documents/report.txt ~/Desktop/report-link.txt создаёт на рабочем столе ссылку report-link.txt, которая ведёт на файл в Documents.
Если второй аргумент опустить, ссылка появится в текущей папке под тем же именем, что у цели. Если указать в качестве второго аргумента существующую папку, ссылка создастся внутри неё. Эти два правила описаны в справке и нередко объясняют, почему ссылка оказалась не там, где её искали.
Типы ссылок такие:
- символическая (ключ -s) — отдельный маленький объект, внутри которого записан путь к цели; работает и для файлов, и для папок;
- жёсткая (без ключа) — ещё одно имя для тех же данных на диске.
Для тренировки используйте тестовую папку: mkdir ~/ln-test и cd ~/ln-test, затем echo hello > original.txt. Все примеры дальше выполняйте там, чтобы не задеть рабочие файлы.
Символическая ссылка на практике
В тестовой папке выполните ln -s original.txt soft.txt и посмотрите на результат командой ls -l. В строке про soft.txt вы увидите стрелку и имя цели: soft.txt -> original.txt. Первая буква в строке прав при этом будет l, что означает ссылку. Чтение soft.txt через cat выдаст содержимое оригинала, потому что система следует по записанному пути.
Важное свойство: путь внутри символической ссылки, если он относительный, отсчитывается от папки, где лежит сама ссылка, а не от того места, где вы запустили команду. Поэтому ссылка, созданная командой ln -s ../data/file.txt link.txt, будет работать только пока эти две папки остаются в таком взаимном положении. Абсолютный путь (начинается с косой черты) такой зависимости не имеет, но он ломается при переносе цели.
Если цель переименовать или удалить, ссылка останется, но станет «битой»: ls -l всё ещё покажет стрелку, а открытие файла даст ошибку об отсутствии файла или каталога. Это не повреждение, а следствие того, что путь больше ничего не находит.
Ключ -f заменяет существующий файл или ссылку с тем же именем, поэтому используйте его осознанно и только на тестовой папке. Для замены ссылки, ведущей на каталог, обычно добавляют ещё ключ -n (запись ln -sfn цель имя); точное поведение смотрите в man ln своей системы, потому что у GNU и BSD версий оно описано по-разному.
Жёсткая ссылка и номер inode
Жёсткая ссылка устроена иначе. Файл на диске описывается служебной записью, у которой есть номер (inode), а имена в папках — это просто записи, указывающие на этот номер. Команда ln original.txt hard.txt добавляет ещё одно имя для той же записи. Увидеть это можно по ls -li: у обоих имён совпадёт первое число (inode), а счётчик ссылок, он стоит в третьем столбце после inode и прав, станет равен двум.
У жёстких ссылок есть ограничения, которые вытекают из такого устройства:
- обе записи должны находиться на одной файловой системе;
- ссылку на каталог обычными средствами создать нельзя;
- у ссылок нет «главного» и «побочного» имён: после удаления одного данные остаются, пока существует хотя бы одно имя.
Изменения содержимого видны через оба имени, потому что данные одни. Если же программа сохраняет файл, создавая новый и подменяя старый, имена могут разойтись: это поведение зависит от программы, и заранее его предсказать не всегда можно.
Проверьте на тесте: echo more >> original.txt, затем cat hard.txt. Строка добавится и в видимом через жёсткую ссылку файле.
Сравнение ссылок по свойствам
Выбор между типами ссылок определяется задачей. Таблица ниже собирает отличия, описанные в документации к ln и принятые в файловых системах Linux и macOS.
| Свойство | Символическая (-s) | Жёсткая |
|---|---|---|
| Можно сделать на папку | да | обычно нет |
| Работает между разными дисками | да | нет |
| Что будет, если цель удалить | ссылка станет «битой» | данные остаются, пока есть имя |
| Видно в ls -l | стрелка -> и буква l | обычный файл со счётчиком больше 1 |
| Занимает место | минимум, хранит путь | почти нет, это лишь запись имени |
На практике символические ссылки применяют, когда нужно дать удобный путь к длинному каталогу: например, короткое имя для папки проекта или один путь к переключаемой версии программы. Жёсткие применяют там, где нужно несколько имён для одних данных без копирования, например в некоторых схемах резервного копирования.
Не стоит рассматривать ссылки как защиту от потери: удаление цели при символической ссылке оставит вас без данных. Резервные копии делаются отдельно, например через rsync, о нём рассказано в соседних материалах.
Как удалить ссылку и найти «битые»
Символическую ссылку удаляют командой rm, как обычный файл: rm soft.txt. Цель при этом остаётся нетронутой, потому что удаляется только запись со стрелкой. Осторожнее со ссылками на каталоги: слеш в конце (rm link/) заставляет систему обратиться к самой цели, а не к ссылке. Результат зависит от версии и ключей: команда может выдать ошибку, а в сочетании с -r риск затронуть содержимое цели существует. Поэтому имя ссылки на папку пишут без слеша, а перед удалением проверяют его командой ls -ld имя.
Чтобы просмотреть, куда ведёт ссылка, используйте ls -l. Есть и команда readlink, которая печатает значение ссылки. В Linux её ключ -f дополнительно приводит путь к полному виду, а в macOS поведение зависит от версии системы, так что сверяйтесь со справкой.
Для поиска ссылок в папке пригодится find с условием -type l. В GNU-версии есть условие -xtype l, которое отбирает ссылки с недоступной целью, но в BSD-варианте оно может отсутствовать. Универсальный способ прост: просматривайте вывод find -type l и проверяйте каждую ссылку на наличие цели через test -e в сочетании с -exec.
Прежде чем удалять найденное, посмотрите на список глазами. Подробнее про find в статье о поиске файла, она указана среди связанных.