[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"/ru/kb/how-to/vps/simvolicheskie-ssylki-kak-sozdat-i-rabotatKbData":3},{"page":4,"pages":110,"recommendedPages":111,"category":69,"categoryTree":69,"total":15,"currentOrder":139,"activeManualCategoryId":69,"tag":-1},{"route":5,"uuid":8,"title":9,"excerpt":10,"content":11,"view_count":12,"published_at":13,"modified_at":13,"like":14,"category":17,"hero_image":62,"seo_metadata":63,"schema_org_metadata":67,"open_graph_metadata":70,"sections":71,"tags":101,"breadcrumbs":102,"images":109},{"language":6,"path":7},"ru","/kb/how-to/vps/simvolicheskie-ssylki-kak-sozdat-i-rabotat","94078842-b665-208c-9277-c4c9ba0c7b54","Символические ссылки: как создать и работать в Linux","Рано или поздно возникает ситуация, когда один и тот же файл нужен сразу в нескольких местах. Копировать его каждый раз – плохое решение: копии расходятся между собой, место на диске тратится впустую, а обновить их все одной командой и тем более быстро откатить изменения обратно не получится.","\n\u003Cp>Рано или поздно возникает ситуация, когда один и тот же файл нужен сразу в нескольких местах. Копировать его каждый раз – плохое решение: копии расходятся между собой, место на диске тратится впустую, а обновить их все одной командой и тем более быстро откатить изменения обратно не получится. В Linux для этого есть механизм полегче – символическая ссылка (symlink).\u003C/p>\n\n\n\n\u003Cp>В этой статье разберем, что такое символические ссылки, чем они отличаются от жестких, что важно учитывать при работе с ними и как создавать, удалять и использовать symlink на практике – с командами, которые можно сразу проверить в терминале.\u003C/p>\n\n\n\n\u003Ch2 id=\"chto-takoe-simvolicheskie-ssylki\">Что такое символические ссылки\u003C/h2>\n\n\n\n\u003Cp>\u003Cstrong>Символическая ссылка\u003C/strong> (от англ. symbolic link, symlink, “симлинк”, “мягкая ссылка”) – это специальный файл, который не содержит данных сам по себе, а хранит путь к другому файлу или директории. По сути, это указатель: когда система или программа обращается к ней, она автоматически перенаправляется по пути, записанному внутри ссылки, к реальному объекту. Например, символическая ссылка на папку позволяет обращаться к каталогу из другого места, не создавая его копию.\u003C/p>\n\n\n\n\u003Cp>Проще всего представить символические ссылки как ярлык в Windows или alias в macOS – только реализованный на уровне файловой системы Linux. Благодаря этому символическая ссылка работает одинаково для любой программы: текстового редактора, веб-сервера, команды \u003Ccode>cat\u003C/code> или скрипта на PHP – все они видят ссылку и автоматически переходят по пути, записанному в ней, к реальному файлу или директории.\u003C/p>\n\n\n\n\u003Cp>Важно понимать: символическая ссылка не хранит содержимое исходного файла и не занимает на диске место, сопоставимое с размером цели, – только текст самого пути. Именно поэтому к одному и тому же файлу или директории можно обращаться сразу из нескольких мест, не дублируя данные и не тратя на это лишнее место.\u003C/p>\n\n\n\n\u003Ch2 id=\"zhestkie-i-simvolicheskie-ssylki-v-chem-otlichie\">Жесткие и символические ссылки: в чем отличие\u003C/h2>\n\n\n\n\u003Cp>Кроме символической, в Linux есть еще один тип ссылок – \u003Cstrong>жесткая ссылка (hard link)\u003C/strong>. Она устроена совсем по-другому, и сравнение с ней хорошо показывает, что на самом деле представляет собой символическая ссылка и почему у нее именно такие возможности и ограничения.\u003C/p>\n\n\n\n\u003Cp>Чтобы понять разницу, нужно вспомнить, как устроена файловая система Linux. В файловой системе каждый объект имеет \u003Cstrong>inode (index node)\u003C/strong> – структуру данных, в которой хранятся его метаданные: владелец, права доступа, размер и другие сведения. При этом имя файла в inode не хранится – оно является частью записи каталога, которая связывает имя с конкретным inode.\u003C/p>\n\n\n\n\u003Cp>Именно из этого принципа и вытекает, что такое жесткая ссылка: это не отдельный файл-указатель, как символическая ссылка, а еще одна запись в директории, которая указывает на тот же inode, что и оригинальный файл. И оригинал, и жесткая ссылки полностью равноправны и ведут к одним и тем же данным на диске – нельзя даже сказать, какое из имен “настоящее”, а какое “ссылка”.\u003C/p>\n\n\n\n\u003Cp>Разница между \u003Cstrong>жесткой (hard link)\u003C/strong> и \u003Cstrong>символической (symlink)\u003C/strong> ссылками видна по нескольким параметрам:\u003C/p>\n\n\n\n\u003Cul>\u003Cli>\u003Cstrong>Inode.\u003C/strong> У жесткой ссылки – тот же inode, что и у оригинала: это буквально второе имя того же файла. У symlink – собственный, отдельный inode: это самостоятельный файл, внутри которого хранится не содержимое, а путь к цели;\u003C/li>\u003Cli>\u003Cstrong>Ссылка на директорию.\u003C/strong> Жесткую ссылку на директорию создать нельзя – это стандартное ограничение файловых систем Linux, чтобы избежать циклов в дереве каталогов. У symlink этого ограничения нет: он может указывать как на файл, так и на директорию;\u003C/li>\u003Cli>\u003Cstrong>Работа между файловыми системами и разделами.\u003C/strong> Жесткая ссылка не может пересекать границу файловой системы – номера inode уникальны только в ее пределах. Symlink этого ограничения не имеет и может ссылаться на объект в другой файловой системе или на другом разделе;\u003C/li>\u003Cli>\u003Cstrong>Поведение при удалении или перемещении оригинала.\u003C/strong> У каждого inode есть счетчик количества жестких ссылок на него (поле \u003Ccode>st_nlink\u003C/code>): данные физически удаляются, только когда счетчик доходит до нуля, то есть когда удалено последнее имя, под которым к файлу можно обратиться. Поэтому жесткая ссылка продолжает работать, даже если удалить “оригинал”, так как оригинал и ссылка равноправны. У symlink такого счетчика нет: если удалить, переименовать или переместить цель, ссылка сразу станет нерабочей (“битой”).\u003C/li>\u003C/ul>\n\n\n\n\u003Cp>Разницу легко увидеть на практике. Если создать файл, жесткую и символическую ссылку на него и посмотреть на номера inode командой \u003Ccode>ls -li\u003C/code>, вывод будет примерно таким:\u003C/p>\n\n\n\n\u003Cdiv class=\"wp-block-beget-code code-block\">\u003Cpre data-options=\"{&quot;mode&quot;:&quot;&quot;}\">\u003Ccode>~$ ls -li original.txt hardlink.txt symlink.txt\n2963 -rw-rw-r-- 2 betutorial betutorial 33 Aug 17 14:38 hardlink.txt\n2963 -rw-rw-r-- 2 betutorial betutorial 33 Aug 17 14:38 original.txt\n3501 lrwxrwxrwx 1 betutorial betutorial 12 Aug 17 14:38 symlink.txt -&gt; original.txt\u003C/code>\u003C/pre>\u003C/div>\n\n\n\n\u003Cp>У \u003Ccode>original.txt\u003C/code> и \u003Ccode>hardlink.txt\u003C/code> номер inode будет одинаковым, у \u003Ccode>symlink.txt\u003C/code> – другим. Также в этом примере видно, что у жесткой ссылки в колонке размера отображается реальный размер файла (это те же данные на диске), а у symlink – длина пути, который в нем записан.\u003C/p>\n\n\n\n\u003Cp>После удаления \u003Ccode>original.txt\u003C/code> жесткая ссылка остается рабочей, а символическая – ломается:\u003C/p>\n\n\n\n\u003Cdiv class=\"wp-block-beget-code code-block\">\u003Cpre data-options=\"{&quot;mode&quot;:&quot;&quot;}\">\u003Ccode>~$ rm original.txt\n~$ cat hardlink.txt\nЭто тестовый файл\n~$ cat symlink.txt\ncat: symlink.txt: No such file or directory\u003C/code>\u003C/pre>\u003C/div>\n\n\n\n\u003Cp>На практике из-за описанных ограничений жесткие ссылки используют редко и для узких задач (например, чтобы у одного и того же файла было сразу два имени в пределах одного раздела), а symlink – гораздо чаще, именно благодаря гибкости: возможности ссылаться на директории и работать между разными файловыми системами.\u003C/p>\n\n\n\n\u003Ch2 id=\"kak-sozdat-udalit-i-obnovit-simvolicheskuyu-ssylku\">Как создать, удалить и обновить символическую ссылку\u003C/h2>\n\n\n\n\u003Cp>В этом разделе разберем, как создать символическую ссылку, удалить и обновить ее, и сразу проверим команды на практике.\u003C/p>\n\n\n\n\u003Cp>Для этого создадим тестовую директорию с файлами:\u003C/p>\n\n\n\n\u003Cdiv class=\"wp-block-beget-code code-block\">\u003Cpre data-options=\"{&quot;mode&quot;:&quot;&quot;}\">\u003Ccode>~$ mkdir ~/symlink-test &amp;&amp; cd ~/symlink-test\n~/symlink-test$ mkdir project\n~/symlink-test$ echo \"Это тестовый файл\" &gt; project/notes.txt\u003C/code>\u003C/pre>\u003C/div>\n\n\n\n\u003Ch3 id=\"sozdanie\">Создание\u003C/h3>\n\n\n\n\u003Cp>Для создания такой ссылки используется команда \u003Ccode>ln\u003C/code> с флагом \u003Ccode>-s\u003C/code>:\u003C/p>\n\n\n\n\u003Cdiv class=\"wp-block-beget-code code-block\">\u003Cpre data-options=\"{&quot;mode&quot;:&quot;&quot;}\">\u003Ccode>ln -s &lt;путь_к_цели&gt; &lt;имя_ссылки&gt;\u003C/code>\u003C/pre>\u003C/div>\n\n\n\n\u003Cp>Создадим символическую ссылку на файл:\u003C/p>\n\n\n\n\u003Cdiv class=\"wp-block-beget-code code-block\">\u003Cpre data-options=\"{&quot;mode&quot;:&quot;&quot;}\">\u003Ccode>~/symlink-test$ ln -s project/notes.txt notes-link.txt\n~/symlink-test$ ls -l notes-link.txt\nlrwxrwxrwx 1 betutorial betutorial 17 Aug 18 08:13 notes-link.txt -&gt; project/notes.txt\n~/symlink-test$ cat notes-link.txt\nЭто тестовый файл\u003C/code>\u003C/pre>\u003C/div>\n\n\n\n\u003Cp>Ссылка на директорию делается точно так же – никакого отдельного флага не требуется:\u003C/p>\n\n\n\n\u003Cdiv class=\"wp-block-beget-code code-block\">\u003Cpre data-options=\"{&quot;mode&quot;:&quot;&quot;}\">\u003Ccode>~/symlink-test$ ln -s project project-link\n~/symlink-test$ ls -l project-link\nlrwxrwxrwx 1 betutorial betutorial 7 Aug 18 08:14 project-link -&gt; project\n~/symlink-test$ ls project\nnotes.txt\n~/symlink-test$ ls project-link\nnotes.txt\u003C/code>\u003C/pre>\u003C/div>\n\n\n\n\u003Cp>Если нужно создать ссылку с тем же именем, что и у цели, но в другой директории, последний аргумент можно опустить – \u003Ccode>ln\u003C/code> возьмет исходное имя файла:\u003C/p>\n\n\n\n\u003Cdiv class=\"wp-block-beget-code code-block\">\u003Cpre data-options=\"{&quot;mode&quot;:&quot;&quot;}\">\u003Ccode>~/symlink-test$ mkdir links &amp;&amp; cd links\n~/symlink-test/links$ ln -s ../project/notes.txt\n~/symlink-test/links$ ls -l\ntotal 0\nlrwxrwxrwx 1 betutorial betutorial 20 Aug 18 08:15 notes.txt -&gt; ../project/notes.txt\n~/symlink-test/links$ cat notes.txt\nЭто тестовый файл\u003C/code>\u003C/pre>\u003C/div>\n\n\n\n\u003Ch3 id=\"udalenie\">Удаление\u003C/h3>\n\n\n\n\u003Cp>Удалить символическую ссылку можно командой \u003Ccode>rm\u003C/code> или \u003Ccode>unlink\u003C/code>. Обе команды могут удалить символическую ссылку, но отличаются набором возможностей:\u003C/p>\n\n\n\n\u003Cul>\u003Cli>\u003Ccode>rm\u003C/code> – может удалить сразу несколько ссылок за один вызов и поддерживает шаблоны (*);\u003C/li>\u003Cli>\u003Ccode>unlink\u003C/code> – может удалить ровно одну ссылку за раз, шаблоны не поддерживает.\u003C/li>\u003C/ul>\n\n\n\n\u003Cp>Проверим удаление символических ссылок: \u003C/p>\n\n\n\n\u003Cdiv class=\"wp-block-beget-code code-block\">\u003Cpre data-options=\"{&quot;mode&quot;:&quot;&quot;}\">\u003Ccode>~/symlink-test$ rm notes-link.txt\n~/symlink-test$ ls -l\ntotal 8\ndrwxrwxr-x 2 betutorial betutorial 4096 Aug 18 08:15 links\ndrwxrwxr-x 2 betutorial betutorial 4096 Aug 18 08:13 project\nlrwxrwxrwx 1 betutorial betutorial    7 Aug 18 08:14 project-link -&gt; project\n~/symlink-test$ unlink project-link\n~/symlink-test$ ls -l\ntotal 8\ndrwxrwxr-x 2 betutorial betutorial 4096 Aug 18 08:15 links\ndrwxrwxr-x 2 betutorial betutorial 4096 Aug 18 08:13 project\n\u003C/code>\u003C/pre>\u003C/div>\n\n\n\n\u003Cp>При удалении символической ссылки ее цель (файл или директория) не удаляется.\u003C/p>\n\n\n\n\u003Cdiv class=\"wp-block-beget-alert alert-block alert-block-info\">\u003Cdiv class=\"alert-block-title\">Обратите внимание!\u003C/div>\u003Cdiv class=\"alert-block-content\">Если путь к символической ссылке на директорию заканчивается на \u003Ccode>/\u003C/code>, система воспринимает такой путь как обращение к директории, на которую указывает ссылка, а не к самой ссылке. Поэтому при удалении символической ссылки завершающий \u003Ccode>/\u003C/code> лучше не указывать.\u003C/div>\u003C/div>\n\n\n\n\u003Cp>Протестируем удаление символической ссылки на директорию с указанием \u003Ccode>/\u003C/code> и без него. Ссылку \u003Ccode>project-link\u003C/code> мы уже удалили выше, поэтому создадим ее заново и попробуем удалить сначала со слэшем, потом без него:\u003C/p>\n\n\n\n\u003Cdiv class=\"wp-block-beget-code code-block\">\u003Cpre data-options=\"{&quot;mode&quot;:&quot;&quot;}\">\u003Ccode>~/symlink-test$ ln -s project project-link\n~/symlink-test$ ls -l project-link\nlrwxrwxrwx 1 betutorial betutorial 7 Aug 18 08:18 project-link -&gt; project\n~/symlink-test$ rm project-link/\nrm: cannot remove 'project-link/': Is a directory\n~/symlink-test$ rm project-link\n~/symlink-test$ ls -l\ntotal 8\ndrwxrwxr-x 2 betutorial betutorial 4096 Aug 18 08:15 links\ndrwxrwxr-x 2 betutorial betutorial 4096 Aug 18 08:13 project\u003C/code>\u003C/pre>\u003C/div>\n\n\n\n\u003Cp>Симлинк на директорию нельзя удалить командой \u003Ccode>rmdir\u003C/code> – она предназначена только для настоящих пустых директорий и вернет ошибку \u003Ccode>Not a directory\u003C/code>.\u003C/p>\n\n\n\n\u003Ch3 id=\"obnovlenie-uzhe-sushchestvuyushchey-simvolicheskoy-ssylki\">Обновление уже существующей символической ссылки\u003C/h3>\n\n\n\n\u003Cp>Отдельная задача – не создать символическую ссылку с нуля, а переключить уже существующую на новую цель. Команда используется одна и та же, но изменяются флаги.\u003C/p>\n\n\n\n\u003Cp>\u003Cstrong>Пример с файлом.\u003C/strong> Пусть ссылка \u003Ccode>config.php\u003C/code> указывает на старый конфиг, и нужно переключить ее на новый:\u003C/p>\n\n\n\n\u003Cdiv class=\"wp-block-beget-code code-block\">\u003Cpre data-options=\"{&quot;mode&quot;:&quot;&quot;}\">\u003Ccode>~/symlink-test$ echo \"старый конфиг\" &gt; config-old.php\n~/symlink-test$ echo \"новый конфиг\" &gt; config-new.php\n~/symlink-test$ ln -s config-old.php config.php\n~/symlink-test$ ls -l config.php\nlrwxrwxrwx 1 betutorial betutorial 14 Aug 18 08:21 config.php -&gt; config-old.php\n~/symlink-test$ cat config.php\nстарый конфиг\u003C/code>\u003C/pre>\u003C/div>\n\n\n\n\u003Cp>Просто повторить \u003Ccode>ln -s\u003C/code> не получится – имя \u003Ccode>config.php\u003C/code> уже занято:\u003C/p>\n\n\n\n\u003Cdiv class=\"wp-block-beget-code code-block\">\u003Cpre data-options=\"{&quot;mode&quot;:&quot;&quot;}\">\u003Ccode>~/symlink-test$ ln -s config-new.php config.php\nln: failed to create symbolic link 'config.php': File exists\u003C/code>\u003C/pre>\u003C/div>\n\n\n\n\u003Cdiv class=\"wp-block-beget-alert alert-block alert-block-info\">\u003Cdiv class=\"alert-block-title\">Обратите внимание!\u003C/div>\u003Cdiv class=\"alert-block-content\">Такая же ошибка появится и в том случае, если с этим именем создан обычный файл, а не ссылка. Прежде чем перезаписывать символическую ссылку, проверьте командой \u003Ccode>ls -l\u003C/code>, что имя действительно принадлежит ссылке, а не файлу с данными.\u003C/div>\u003C/div>\n\n\n\n\u003Cp>Для перезаписи ссылки добавляем флаг \u003Ccode>-f\u003C/code> (\u003Ccode>--force\u003C/code>, “принудительно”) – он указывает \u003Ccode>ln\u003C/code> не выдавать ошибку, а удалить существующий файл или ссылку с этим именем и создать на его месте новую:\u003C/p>\n\n\n\n\u003Cdiv class=\"wp-block-beget-code code-block\">\u003Cpre data-options=\"{&quot;mode&quot;:&quot;&quot;}\">\u003Ccode>~/symlink-test$ ln -sf config-new.php config.php\n~/symlink-test$ ls -l config.php\nlrwxrwxrwx 1 betutorial betutorial 14 Aug 18 08:23 config.php -&gt; config-new.php\n~/symlink-test$ cat config.php\nновый конфиг\u003C/code>\u003C/pre>\u003C/div>\n\n\n\n\u003Cp>\u003Cstrong>Пример с директорией.\u003C/strong> Пусть \u003Ccode>current\u003C/code> указывает на директорию \u003Ccode>release-1\u003C/code>:\u003C/p>\n\n\n\n\u003Cdiv class=\"wp-block-beget-code code-block\">\u003Cpre data-options=\"{&quot;mode&quot;:&quot;&quot;}\">\u003Ccode>~/symlink-test$ mkdir release-1 release-2\n~/symlink-test$ echo \"версия 1\" &gt; release-1/version.txt\n~/symlink-test$ echo \"версия 2\" &gt; release-2/version.txt\n~/symlink-test$ ln -s release-1 current\n~/symlink-test$ ls -l current\nlrwxrwxrwx 1 betutorial betutorial 9 Aug 18 08:23 current -&gt; release-1\n~/symlink-test$ cat current/version.txt\nверсия 1\u003C/code>\u003C/pre>\u003C/div>\n\n\n\n\u003Cp>Попробуем переключить \u003Ccode>current\u003C/code> на \u003Ccode>release-2\u003C/code> тем же способом:\u003C/p>\n\n\n\n\u003Cdiv class=\"wp-block-beget-code code-block\">\u003Cpre data-options=\"{&quot;mode&quot;:&quot;&quot;}\">\u003Ccode>~/symlink-test$ ln -sf release-2 current\n~/symlink-test$ ls -l current\nlrwxrwxrwx 1 betutorial betutorial 9 Aug 18 08:23 current -&gt; release-1\n~/symlink-test$ cat current/version.txt\nверсия 1\u003C/code>\u003C/pre>\u003C/div>\n\n\n\n\u003Cp>Символическая ссылка \u003Ccode>current\u003C/code> не изменилась. Утилита \u003Ccode>ln\u003C/code> обнаружила, что \u003Ccode>current\u003C/code> ведет на директорию, перешла внутрь нее, создав там новую ссылку с именем \u003Ccode>release-2\u003C/code> – вместо того, чтобы заменить симлинк \u003Ccode>current\u003C/code>:\u003C/p>\n\n\n\n\u003Cdiv class=\"wp-block-beget-code code-block\">\u003Cpre data-options=\"{&quot;mode&quot;:&quot;&quot;}\">\u003Ccode>~/symlink-test/release-1$ ls -l\ntotal 4\nlrwxrwxrwx 1 betutorial betutorial  9 Aug 18 08:24 release-2 -&gt; release-2\n-rw-rw-r-- 1 betutorial betutorial 15 Aug 18 08:23 version.txt\u003C/code>\u003C/pre>\u003C/div>\n\n\n\n\u003Cp>Чтобы заменить именно \u003Ccode>current\u003C/code>, а не создать ссылку внутри ее цели, нужен еще один флаг – \u003Ccode>-n\u003C/code> (\u003Ccode>--no-dereference\u003C/code>, “не переходить по ссылке”) – он указывает \u003Ccode>ln\u003C/code> воспринимать \u003Ccode>current\u003C/code> как обычное имя, а не заходить внутрь директории, на которую эта ссылка сейчас указывает:\u003C/p>\n\n\n\n\u003Cdiv class=\"wp-block-beget-code code-block\">\u003Cpre data-options=\"{&quot;mode&quot;:&quot;&quot;}\">\u003Ccode>~/symlink-test$ ln -sfn release-2 current\n~/symlink-test$ ls -l current\nlrwxrwxrwx 1 betutorial betutorial 9 Aug 18 08:26 current -&gt; release-2\n~/symlink-test$ cat current/version.txt\nверсия 2\u003C/code>\u003C/pre>\u003C/div>\n\n\n\n\u003Cp>Ту же задачу можно решить и проще – удалить старую ссылку и создать новую:\u003C/p>\n\n\n\n\u003Cdiv class=\"wp-block-beget-code code-block\">\u003Cpre data-options=\"{&quot;mode&quot;:&quot;&quot;}\">\u003Ccode>rm current\nln -s release-2 current\u003C/code>\u003C/pre>\u003C/div>\n\n\n\n\u003Cp>Для тестов и разовых задач данный способ подойдет. Для боевого сервера, где \u003Ccode>current\u003C/code> – это, например, \u003Ccode>document root\u003C/code> работающего сайта, у такого способа есть нюанс: между \u003Ccode>rm\u003C/code> и \u003Ccode>ln -s\u003C/code> есть короткий промежуток времени, когда пути \u003Ccode>current\u003C/code> не существует вообще, и случайный запрос в это время может получить ошибку. Команда \u003Ccode>ln -sfn\u003C/code> заменяет ссылку одной операцией без простоя.\u003C/p>\n\n\n\n\u003Ch2 id=\"nyuansy-kotorye-vazhno-uchityvat-pri-rabote-s-symlink\">Нюансы, которые важно учитывать при работе с symlink\u003C/h2>\n\n\n\n\u003Cp>У симлинка есть несколько особенностей поведения, из-за которых он может повести себя не так, как ожидается.&nbsp;\u003C/p>\n\n\n\n\u003Cp>Чтобы не путать эти примеры с уже созданными файлами и ссылками, создадим для них отдельную тестовую директорию:\u003C/p>\n\n\n\n\u003Cdiv class=\"wp-block-beget-code code-block\">\u003Cpre data-options=\"{&quot;mode&quot;:&quot;&quot;}\">\u003Ccode>~$ mkdir ~/symlink-test2 &amp;&amp; cd ~/symlink-test2\n~/symlink-test2$ echo \"Это тестовый файл\" &gt; notes.txt\u003C/code>\u003C/pre>\u003C/div>\n\n\n\n\u003Cp>\u003Cstrong>Абсолютный или относительный путь.\u003C/strong> Ссылку можно создать с абсолютным путем или относительным. Это важно при переносе файлов: относительная ссылка останется рабочей, если переместить и ссылку, и цель в новое место вместе, сохранив их взаимное расположение, а абсолютная – только если не менять расположение самой цели.\u003C/p>\n\n\n\n\u003Cdiv class=\"wp-block-beget-code code-block\">\u003Cpre data-options=\"{&quot;mode&quot;:&quot;&quot;}\">\u003Ccode>~/symlink-test2$ ln -s \"$(pwd)/notes.txt\" abs-link.txt\n~/symlink-test2$ ln -s notes.txt rel-link.txt\n~/symlink-test2$ readlink abs-link.txt\n/home/betutorial/symlink-test2/notes.txt\n~/symlink-test2$ readlink rel-link.txt\nnotes.txt\u003C/code>\u003C/pre>\u003C/div>\n\n\n\n\u003Cp>Видно, что \u003Ccode>readlink\u003C/code> возвращает именно тот путь, который был записан в ссылку при создании, – в первом случае полный, во втором относительный.\u003C/p>\n\n\n\n\u003Cp>\u003Cstrong>Symlink можно создать на несуществующую цель.\u003C/strong> Linux не проверяет при создании символической ссылки, существует ли путь, на который она указывает, – ошибки не будет, даже если будет опечатка в пути:\u003C/p>\n\n\n\n\u003Cdiv class=\"wp-block-beget-code code-block\">\u003Cpre data-options=\"{&quot;mode&quot;:&quot;&quot;}\">\u003Ccode>~/symlink-test2$ ln -s not-yet-created.txt future-link.txt\n~/symlink-test2$ ls -l future-link.txt\nlrwxrwxrwx 1 betutorial betutorial 19 Aug 18 11:38 future-link.txt -&gt; not-yet-created.txt\n~/symlink-test2$ cat future-link.txt\ncat: future-link.txt: No such file or directory\u003C/code>\u003C/pre>\u003C/div>\n\n\n\n\u003Cp>\u003Cstrong>Ссылка может стать “битой” в любой момент своей жизни\u003C/strong> – если цель удалили, переименовали или переместили. Найти все битые ссылки в директории можно при помощи утилиты \u003Ccode>find\u003C/code>:\u003C/p>\n\n\n\n\u003Cdiv class=\"wp-block-beget-code code-block\">\u003Cpre data-options=\"{&quot;mode&quot;:&quot;&quot;}\">\u003Ccode>~/symlink-test2$ find . -xtype l\n./future-link.txt\nА потом узнать, куда именно ведет конкретная ссылка:\n~/symlink-test2$ readlink future-link.txt\nnot-yet-created.txt\n~/symlink-test2$ readlink -f future-link.txt\n/home/betutorial/symlink-test2/not-yet-created.txt\u003C/code>\u003C/pre>\u003C/div>\n\n\n\n\u003Cp>\u003Ccode>readlink\u003C/code> возвращает путь ровно в том виде, в каком он записан в ссылке, а \u003Ccode>readlink -f\u003C/code> разворачивает его в полный абсолютный путь.\u003C/p>\n\n\n\n\u003Cp>\u003Cstrong>Symlink может указывать на другую ссылку, образуя цепочку.\u003C/strong> Система разворачивает такие цепочки автоматически, но если ссылки образуют цикл (ссылаются друг на друга), при обращении к ним будет ошибка:\u003C/p>\n\n\n\n\u003Cdiv class=\"wp-block-beget-code code-block\">\u003Cpre data-options=\"{&quot;mode&quot;:&quot;&quot;}\">\u003Ccode>~/symlink-test2$ ln -s notes.txt chain1.txt\n~/symlink-test2$ ln -s chain1.txt chain2.txt\n~/symlink-test2$ readlink chain2.txt\nchain1.txt\n~/symlink-test2$ readlink -f chain2.txt\n/home/betutorial/symlink-test2/notes.txt\n~/symlink-test2$ ln -s loop2.txt loop1.txt\n~/symlink-test2$ ln -s loop1.txt loop2.txt\n~/symlink-test2$ cat loop1.txt\ncat: loop1.txt: Too many levels of symbolic links\u003C/code>\u003C/pre>\u003C/div>\n\n\n\n\u003Ch2 id=\"primery-ispolzovaniya-simvolicheskih-ssylok\">Примеры использования символических ссылок\u003C/h2>\n\n\n\n\u003Cp>Рассмотрим несколько типичных задач, в которых symlink находит применение на практике:\u003C/p>\n\n\n\n\u003Col>\u003Cli>\u003Cstrong>Обновление сайта без остановки (деплой релизов)\u003C/strong>\u003C/li>\u003C/ol>\n\n\n\n\u003Cp>Каждая версия сайта разворачивается в отдельную директорию с номером или датой релиза, а на актуальную указывает единый symlink \u003Ccode>current\u003C/code> – именно он настроен как document root веб-сервера:\u003C/p>\n\n\n\n\u003Cdiv class=\"wp-block-beget-code code-block\">\u003Cpre data-options=\"{&quot;mode&quot;:&quot;&quot;}\">\u003Ccode>ln -sfn /var/www/site/releases/2026-08-15 /var/www/site/current\u003C/code>\u003C/pre>\u003C/div>\n\n\n\n\u003Cp>Обновление сводится к одной команде – переключить ссылку на новый релиз. Откат к предыдущей версии делается точно так же, без повторной выгрузки файлов. Благодаря этому переключение происходит мгновенно и без простоя.\u003C/p>\n\n\n\n\u003Col start=\"2\">\u003Cli>\u003Cstrong>Переключение между версиями Python, Node.js и других сред\u003C/strong>\u003C/li>\u003C/ol>\n\n\n\n\u003Cp>Если на сервере установлено несколько версий одного языка или рантайма (например, \u003Ccode>/opt/node-18\u003C/code> и \u003Ccode>/opt/node-20\u003C/code>), удобно не переписывать пути в каждом проекте или скрипте при переходе на новую версию, а один раз добавить символическую ссылку и переключать ее:\u003C/p>\n\n\n\n\u003Cdiv class=\"wp-block-beget-code code-block\">\u003Cpre data-options=\"{&quot;mode&quot;:&quot;&quot;}\">\u003Ccode>ln -sfn /opt/node-20 /usr/local/node\u003C/code>\u003C/pre>\u003C/div>\n\n\n\n\u003Cp>Все проекты и скрипты обращаются к \u003Ccode>/usr/local/node/bin/node\u003C/code> и не знают, какая версия установлена на самом деле. Перейти на другую версию – значит перелинковать одну ссылку, а не искать и менять путь во всех местах, где он был прописан. Если новая версия окажется несовместимой, откат назад – снова одна команда.\u003C/p>\n\n\n\n\u003Col start=\"3\">\u003Cli>\u003Cstrong>Хранение загружаемых файлов на отдельном диске\u003C/strong>\u003C/li>\u003C/ol>\n\n\n\n\u003Cp>Когда файлы, которые загружают пользователи, растут быстрее, чем код приложения, их удобно вынести на отдельный диск или раздел, а в директории сайта оставить только ссылку:\u003C/p>\n\n\n\n\u003Cdiv class=\"wp-block-beget-code code-block\">\u003Cpre data-options=\"{&quot;mode&quot;:&quot;&quot;}\">\u003Ccode>ln -s /mnt/storage/uploads /var/www/site/uploads\u003C/code>\u003C/pre>\u003C/div>\n\n\n\n\u003Cp>Код приложения продолжает работать с привычным путем \u003Ccode>uploads/\u003C/code>, ничего в нем менять не нужно, а хранилище можно расширять независимо от диска с самим сайтом.\u003C/p>\n\n\n\n\u003Col start=\"4\">\u003Cli>\u003Cstrong>Включение и отключение сайтов в Nginx\u003C/strong>\u003C/li>\u003C/ol>\n\n\n\n\u003Cp>В \u003Ca href=\"https://beget.com/ru/cloud/marketplace/debian-12?utm_source=kb&amp;utm_medium=article&amp;utm_campaign=symbolic_links&amp;utm_content=marketplace_debian_12\">Debian\u003C/a> и \u003Ca href=\"https://beget.com/ru/cloud/marketplace/ubuntu-24-04?utm_source=kb&amp;utm_medium=article&amp;utm_campaign=symbolic_links&amp;utm_content=marketplace_ubuntu_24_04\">Ubuntu\u003C/a> конфигурации сайтов принято хранить в \u003Ccode>sites-available\u003C/code>, а подключать – символической ссылкой из \u003Ccode>sites-enabled\u003C/code>:\u003C/p>\n\n\n\n\u003Cdiv class=\"wp-block-beget-code code-block\">\u003Cpre data-options=\"{&quot;mode&quot;:&quot;&quot;}\">\u003Ccode>ln -s /etc/nginx/sites-available/example.com.conf /etc/nginx/sites-enabled/example.com.conf\u003C/code>\u003C/pre>\u003C/div>\n\n\n\n\u003Cp>Отключить сайт – значит просто удалить ссылку, не трогая сам файл конфигурации. Это удобнее, чем закомментировать блок \u003Ccode>server\u003C/code> или хранить несколько версий одного конфига: включение и отключение сайта не требуют правок самого файла и не рискуют испортить его синтаксис.\u003C/p>\n\n\n\n\u003Ch2 id=\"zaklyuchenie\">Заключение\u003C/h2>\n\n\n\n\u003Cp>\u003Cstrong>Symlink\u003C/strong> – это простой указатель на другой файл или директорию: не копия, а еще один путь к тем же данным. В отличие от жесткой ссылки, он может вести на директорию и работать между разными дисками и разделами, но зато способен “сломаться”, если цель удалят или переместят.\u003C/p>\n\n\n\n\u003Cp>Для повседневной работы достаточно нескольких команд: \u003Ccode>ln -s\u003C/code> – создать ссылку, \u003Ccode>ln -sfn\u003C/code> – заменить существующую, \u003Ccode>rm\u003C/code> или \u003Ccode>unlink\u003C/code> – удалить, \u003Ccode>readlink -f \u003C/code>– проверить, куда она ведет, даже если цель не существует. С этим набором symlink пригодится и для деплоя, и для организации файлов на сервере, и для десятков других задач, где не хочется дублировать данные.\u003C/p>\n\n\n\n\u003Cp>Если возникнут вопросы, напишите нам, пожалуйста, тикет из панели управления аккаунта (раздел “\u003Ca href=\"https://cp.beget.com/support?utm_source=kb&amp;utm_medium=article&amp;utm_campaign=symbolic_links&amp;utm_content=cp_support\">Помощь и поддержка\u003C/a>”), а если вы захотите обсудить эту статью или наши продукты с коллегами по цеху и сотрудниками Beget – ждем вас в нашем \u003Ca href=\"https://t.me/beget_chat\">сообществе\u003C/a> в Telegram.&nbsp;\u003C/p>\n",11,"2026-08-21T15:48:41.000Z",{"count":15,"liked":16},0,false,{"route":18,"title":20,"tags":21,"breadcrumbs":54,"uuid":55,"parent_uuid":56,"default_page_path":25,"seo_metadata":57},{"language":6,"path":19},"/kb/how-to/vps","VPS",[22,26,30,34,38,42,46,50],{"id":23,"title":20,"seo_metadata":24},"vps",{"title":25,"description":25,"header":25,"keywords":25},"",{"id":27,"title":28,"seo_metadata":29},"apache","Apache",{"title":25,"description":25,"header":25,"keywords":25},{"id":31,"title":32,"seo_metadata":33},"lets-encrypt","Let's Encrypt",{"title":25,"description":25,"header":25,"keywords":25},{"id":35,"title":36,"seo_metadata":37},"nginx","Nginx",{"title":25,"description":25,"header":25,"keywords":25},{"id":39,"title":40,"seo_metadata":41},"ssl","SSL",{"title":25,"description":25,"header":25,"keywords":25},{"id":43,"title":44,"seo_metadata":45},"vestacp","VestaCP",{"title":25,"description":25,"header":25,"keywords":25},{"id":47,"title":48,"seo_metadata":49},"perenos-sajta","Перенос сайта",{"title":25,"description":25,"header":25,"keywords":25},{"id":51,"title":52,"seo_metadata":53},"terminal","Терминал",{"title":25,"description":25,"header":25,"keywords":25},[],"957abe7d-4a90-1475-bfb0-6439507ed391","fa9a1354-631a-4206-df34-291f0db8f42a",{"title":58,"description":59,"header":60,"keywords":61},"VPS. Полезные статьи – Beget","Полезные статьи о VPS на сайте Beget","VPS. Полезные статьи","vps, вопрос ответ",{"src":25,"text":25},{"title":64,"description":65,"keywords":66},"Символические ссылки – что это? Создание и особенности работы","Что такое символические ссылки? Какое отличие от жестких ссылок в Linux? Особенности специального файла в системе","Как работать с symlink, мягкие и жесткие ссылки в файловой системе Linux, основные особенности символических ссылок",{"faq":68,"how_to":69,"product":69},[],null,{},[72,76,79,82,86,89,92,95,98],{"level":73,"name":74,"anchor":75},1,"Что такое символические ссылки","chto-takoe-simvolicheskie-ssylki",{"level":73,"name":77,"anchor":78},"Жесткие и символические ссылки: в чем отличие","zhestkie-i-simvolicheskie-ssylki-v-chem-otlichie",{"level":73,"name":80,"anchor":81},"Как создать, удалить и обновить символическую ссылку","kak-sozdat-udalit-i-obnovit-simvolicheskuyu-ssylku",{"level":83,"name":84,"anchor":85},2,"Создание","sozdanie",{"level":83,"name":87,"anchor":88},"Удаление","udalenie",{"level":83,"name":90,"anchor":91},"Обновление уже существующей символической ссылки","obnovlenie-uzhe-sushchestvuyushchey-simvolicheskoy-ssylki",{"level":73,"name":93,"anchor":94},"Нюансы, которые важно учитывать при работе с symlink","nyuansy-kotorye-vazhno-uchityvat-pri-rabote-s-symlink",{"level":73,"name":96,"anchor":97},"Примеры использования символических ссылок","primery-ispolzovaniya-simvolicheskih-ssylok",{"level":73,"name":99,"anchor":100},"Заключение","zaklyuchenie",[],[103,107],{"route":104,"title":106},{"language":6,"path":105},"/kb/how-to","Полезные статьи",{"route":108,"title":20},{"language":6,"path":19},[],[],[112,121,130],{"route":113,"uuid":115,"title":116,"excerpt":25,"content":25,"view_count":15,"published_at":25,"modified_at":25,"like":69,"category":69,"hero_image":69,"seo_metadata":69,"schema_org_metadata":69,"open_graph_metadata":69,"sections":117,"tags":118,"breadcrumbs":119,"images":120},{"language":6,"path":114},"/kb/how-to/vps/ustanovka-ruby-i-ruby-on-rails-s-pomoshhyu-rbenv-na-ubuntu-22-04","be519eea-29a6-758a-a028-9b3bd39b924b","Установка Ruby и Ruby on Rails с помощью rbenv на Ubuntu 22.04",[],[],[],[],{"route":122,"uuid":124,"title":125,"excerpt":25,"content":25,"view_count":15,"published_at":25,"modified_at":25,"like":69,"category":69,"hero_image":69,"seo_metadata":69,"schema_org_metadata":69,"open_graph_metadata":69,"sections":126,"tags":127,"breadcrumbs":128,"images":129},{"language":6,"path":123},"/kb/how-to/vps/kak-rabotat-s-docker-cherez-portainer","6937ba9a-1abd-4289-ae71-3c62e10f8240","Как работать с Docker через Portainer",[],[],[],[],{"route":131,"uuid":133,"title":134,"excerpt":25,"content":25,"view_count":15,"published_at":25,"modified_at":25,"like":69,"category":69,"hero_image":69,"seo_metadata":69,"schema_org_metadata":69,"open_graph_metadata":69,"sections":135,"tags":136,"breadcrumbs":137,"images":138},{"language":6,"path":132},"/kb/how-to/vps/cloud-db-using-example","a8c70d33-21fe-dfbd-288b-e8ccb07df9f2","Настройка облачного сервера MySQL",[],[],[],[],"popularity-desc"]