Вы когда-нибудь слышали о концепции символических ссылок в Linux?

Возможно, вы слышали слово «символическая ссылка»… это одно и то же.

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

Символическая ссылка в Linux (или Unix-подобных операционных системах) — это ярлык для файла или каталога. Вы можете использовать его для упрощения доступа к файлу или каталогу, если их путь длинный или его трудно запомнить. Команда ln позволяет создавать символические ссылки в системе Linux.

В этой статье мы поработаем с командой ln, чтобы познакомиться с созданием символических ссылок в Linux.

Начнем!

Символическая ссылка на файл в Linux

Зачем создавать символическую ссылку на файл в Linux?

Одна из причин — необходимость ссылаться на файлы в нашей системе Linux более общим образом.

Например, я создал каталог отчетов, в котором каждый месяц автоматизированный скрипт (не являющийся частью этого руководства) создает отчет о ежемесячных расходах моего бизнеса.

Ниже вы можете увидеть содержимое каталога отчетов:

[ec2-user@ip-172-31-1-2 reports]$ ls -ltr
total 0
-rw-rw-r-- 1 ec2-user ec2-user 12 May  1 14:50 report_April2020
-rw-rw-r-- 1 ec2-user ec2-user 12 Jun  1 14:50 report_May2020
-rw-rw-r-- 1 ec2-user ec2-user 12 Jul  1 14:50 report_June2020
-rw-rw-r-- 1 ec2-user ec2-user 12 Aug  1 14:50 report_July2020

Допустим, я хочу иметь автоматизированный способ доступа к последнему отчету, не зная его названия (которое меняется из месяца в месяц).

Я могу обновить скрипт, который генерирует ежемесячный отчет, чтобы также создать символическую ссылку с именем last_report, указывающую на самый последний сгенерированный отчет.

В этом конкретном случае скрипт, генерирующий отчет за июль, также выполнит следующую команду:

ln -s report_July2020 last_report

С помощью команды ls мы можем увидеть созданную символическую ссылку:

lrwxrwxrwx 1 ec2-user ec2-user 15 Aug  1 14:57 last_report -> report_July2020

Таким образом, я могу просмотреть содержимое последнего отчета, просто используя команду:

cat last_report

Что происходит при формировании отчета за следующий месяц?

Наш скрипт должен перенаправить символическую ссылку с report_July2020 на report_August2020 с помощью команд unlink и ln:

[ec2-user@ip-172-31-1-2 reports]$ unlink last_report 
[ec2-user@ip-172-31-1-2 reports]$ ln -s report_August2020 last_report
[ec2-user@ip-172-31-1-2 reports]$ ls -ltr
total 16
-rw-rw-r-- 1 ec2-user ec2-user 12 May  1 14:50 report_April2020
-rw-rw-r-- 1 ec2-user ec2-user 12 Jun  1 14:50 report_May2020
-rw-rw-r-- 1 ec2-user ec2-user 12 Jul  1 14:50 report_June2020
-rw-rw-r-- 1 ec2-user ec2-user 12 Aug  1 14:50 report_July2020
-rw-rw-r-- 1 ec2-user ec2-user 12 Sep  1 14:50 report_August2020
lrwxrwxrwx 1 ec2-user ec2-user 17 Sep  1 14:50 last_report -> report_August2020

Имеет ли это смысл?

Символическая ссылка на каталог в Linux

Давайте рассмотрим пример того, как можно создать символическую ссылку на каталог Linux.

Создайте новый каталог в /opt/scripts/:

mkdir -p /opt/scripts/this/is/a/complex/path/ 

Вы можете видеть, что мы передаем флаг -p команде mkdir. Этот флаг используется для создания любых каталогов в этом пути, если они не существуют.

Вот что происходит без флага -p (мы заменяем каталог this на this2):

mkdir /opt/scripts/this2/is/a/complex/path/
mkdir: cannot create directory ‘/opt/scripts/this2/is/a/complex/path/’: No such file or directory 

Затем мы создаем файл с именем test.txt в каталоге /opt/scripts/this/is/a/complex/path/.

echo "This is our test file" > /opt/scripts/this/is/a/complex/path/test.txt

Как видите, мы использовали команду echo и перенаправление для создания файла, содержащего одну строку с текстом «Это наш тестовый файл».

Теперь мы хотим получить доступ к этому файлу, не запоминая этот сложный путь.

В /opt/scripts/ мы создаем символическую ссылку с именем complex_path на каталог, в котором находится файл.

cd /opt/scripts/
ln -s /opt/scripts/this/is/a/complex/path/ complex_path

Формат команды ln:

ln -s <source_directory> <target_directory>

Где source_directory — существующий каталог, а target_directory — имя создаваемой нами ссылки.

Вот что мы получаем при создании символической ссылки complex_path:

[ec2-user@localhost scripts]$ pwd
/opt/scripts
[ec2-user@localhost scripts]$ ls -al complex_path
lrwxrwxrwx 1 ec2-user ec2-user 36 Mar 17 23:54 complex_path -> /opt/scripts/this/is/a/complex/path/ 

А теперь давайте перейдем в каталог, связанный с символической ссылкой, и используем pwd для проверки рабочего каталога:

[ec2-user@localhost scripts]$ cd complex_path/
[ec2-user@localhost complex_path]$ pwd
/opt/scripts/complex_path 

Как вы можете видеть, команда pwd показывает логический путь к каталогу вместо фактического реального пути к каталогу, на который ссылается символическая ссылка…

Чтобы показать физический путь, нам нужно использовать флаг -P:

[ec2-user@localhost complex_path]$ pwd -P
/opt/scripts/this/is/a/complex/path 

Если мы используем ls, то увидим, что в каталоге complex_path находится файл test.txt, который мы создали в начале:

[ec2-user@localhost complex_path]$ ls -al
total 4
drwxrwxr-x 2 ec2-user ec2-user 22 Mar 18 00:14.
drwxrwxr-x 3 ec2-user ec2-user 18 Mar 17 23:50..
-rw-rw-r-- 1 ec2-user ec2-user 22 Mar 17 23:54 test.txt 

Удаление символической ссылки

Что произойдет, если символическая ссылка вам больше не нужна?

Вы можете удалить его с помощью команды unlink:

cd /opt/scripts/
unlink complex_path

[ec2-user@localhost scripts]$ ls -al complex_path
ls: cannot access complex_path: No such file or directory 

Очень часто команды unlink и ln используются вместе, если мы хотим указать символическую ссылку на другой каталог.

Это распространенная ситуация при выпуске новой версии программного обеспечения…

Предположим, текущая версия вашего программного обеспечения находится в каталоге my_software_v1, и вы хотите создать общую символическую ссылку с именем my_software, чтобы вам не приходилось помнить, какая версия вашего программного обеспечения активна.

У вас будет что-то вроде:

lrwxrwxrwx 1 ec2-user ec2-user  14 Mar 18 00:21 my_software -> my_software_v1
drwxrwxr-x 2 ec2-user ec2-user   6 Mar 18 00:21 my_software_v1 

Пришло время выпустить версию 2 вашего программного обеспечения, поэтому вы создаете каталог my_software_v2.

[ec2-user@localhost software]$ mkdir my_software_v2
[ec2-user@localhost software]$ ls -al
total 0
drwxrwxr-x 4 ec2-user ec2-user  69 Mar 18 00:23.
drwxr-xr-x 5 ec2-user ec2-user 185 Mar 18 00:21..
lrwxrwxrwx 1 ec2-user ec2-user  14 Mar 18 00:21 my_software -> my_software_v1
drwxrwxr-x 2 ec2-user ec2-user   6 Mar 18 00:21 my_software_v1
drwxrwxr-x 2 ec2-user ec2-user   6 Mar 18 00:23 my_software_v2 

Итак, как перенаправить символическую ссылку на новую версию вашего программного обеспечения?

  • Удалить существующую символическую ссылку
  • Создайте заново символическую ссылку, на этот раз указывающую на my_software_v2.
[ec2-user@localhost software]$ unlink my_software
[ec2-user@localhost software]$ ln -s my_software_v2 my_software
[ec2-user@localhost software]$ ls -al
total 0
drwxrwxr-x 4 ec2-user ec2-user  69 Mar 18 00:25.
drwxr-xr-x 5 ec2-user ec2-user 185 Mar 18 00:21..
lrwxrwxrwx 1 ec2-user ec2-user  14 Mar 18 00:25 my_software -> my_software_v2
drwxrwxr-x 2 ec2-user ec2-user   6 Mar 18 00:21 my_software_v1
drwxrwxr-x 2 ec2-user ec2-user   6 Mar 18 00:23 my_software_v2 

Таким образом, вы можете получить доступ к каталогу вашего последнего программного обеспечения, просто используя символическую ссылку my_software.

Это распространенный метод, используемый, когда вам необходимо выпустить новую версию вашего программного обеспечения на сервере Linux.

Как связать все файлы в каталоге с помощью символических ссылок

Распространенный вопрос: как создать символические ссылки для всех файлов в каталоге.

Давайте рассмотрим это на примере…

Я создал каталог firstdir в /var/tmp/ и он содержит следующие файлы:

[ec2-user@ip-172-31-1-2 tmp]$ ls -al first_dir/
total 0
drwxrwxr-x 2 ec2-user ec2-user  91 Aug  2 19:12.
drwxrwxrwt 6 root     root     133 Aug  2 19:12..
-rw-rw-r-- 1 ec2-user ec2-user   0 Aug  2 19:12 testfile1
-rw-rw-r-- 1 ec2-user ec2-user   0 Aug  2 19:12 testfile2
-rw-rw-r-- 1 ec2-user ec2-user   0 Aug  2 19:12 testfile3
-rw-rw-r-- 1 ec2-user ec2-user   0 Aug  2 19:12 testfile4
-rw-rw-r-- 1 ec2-user ec2-user   0 Aug  2 19:12 testfile5

Чтобы создать символические ссылки в каталоге /var/tmp/second_dir, указывающие на файлы в first_dir, выполните (из любого каталога) следующую команду:

ln -s /var/tmp/first_dir/* /var/tmp/second_dir/

Вот как выглядит содержимое second_dir после выполнения команды:

[ec2-user@ip-172-31-1-2 tmp]$ ls -al second_dir/
total 0
drwxrwxr-x 2 ec2-user ec2-user  91 Aug  2 19:18.
drwxrwxrwt 6 root     root     135 Aug  2 19:17..
lrwxrwxrwx 1 ec2-user ec2-user  28 Aug  2 19:18 testfile1 -> /var/tmp/first_dir/testfile1
lrwxrwxrwx 1 ec2-user ec2-user  28 Aug  2 19:18 testfile2 -> /var/tmp/first_dir/testfile2
lrwxrwxrwx 1 ec2-user ec2-user  28 Aug  2 19:18 testfile3 -> /var/tmp/first_dir/testfile3
lrwxrwxrwx 1 ec2-user ec2-user  28 Aug  2 19:18 testfile4 -> /var/tmp/first_dir/testfile4
lrwxrwxrwx 1 ec2-user ec2-user  28 Aug  2 19:18 testfile5 -> /var/tmp/first_dir/testfile5

Обязательно используйте абсолютный путь для обоих каталогов в команде ln, в противном случае вы можете создать символические ссылки в second_dir, указывающие на неверный относительный путь.

Другим вариантом может быть использование относительных путей в команде ln вместо абсолютных.

Предположим, что мы еще не создали никаких символических ссылок в second_dir…

Откройте каталог second_dir с помощью команды cd и выполните следующую команду:

[ec2-user@ip-172-31-1-2 second_dir]$ ln -s../first_dir/*.

На этот раз мы использовали относительные пути, исходя из того, что при создании символических ссылок мы находимся в каталоге second_dir.

Точка (.) в конце команды ln -s указывает команде на необходимость создания символических ссылок в текущем каталоге.

Вот как выглядит содержимое second_dir:

[ec2-user@ip-172-31-1-2 second_dir]$ ls -al
total 0
drwxrwxr-x 2 ec2-user ec2-user  91 Aug  2 19:52.
drwxrwxrwt 6 root     root     135 Aug  2 19:17..
lrwxrwxrwx 1 ec2-user ec2-user  22 Aug  2 19:52 testfile1 ->../first_dir/testfile1
lrwxrwxrwx 1 ec2-user ec2-user  22 Aug  2 19:52 testfile2 ->../first_dir/testfile2
lrwxrwxrwx 1 ec2-user ec2-user  22 Aug  2 19:52 testfile3 ->../first_dir/testfile3
lrwxrwxrwx 1 ec2-user ec2-user  22 Aug  2 19:52 testfile4 ->../first_dir/testfile4
lrwxrwxrwx 1 ec2-user ec2-user  22 Aug  2 19:52 testfile5 ->../first_dir/testfile5

Имеет ли это смысл?

Заключение

В этой статье вы узнали, как использовать:

  • Команда ln для создания символической ссылки на файл или каталог в Linux
  • команда echo для создания нового файла
  • Команда mkdir для создания вложенной структуры каталогов
  • Команда pwd для отображения физического пути к текущему каталогу
  • команда unlink для удаления символической ссылки

Вы также узнали, как создавать символические ссылки на все файлы в каталоге!

А вы используете символические ссылки? Если да, то как?

Written by Иван Васильков

Системный администратор и DevOps с опытом 10+ лет.