Почему & ldquo; ln & rdquo; Команде нужен абсолютный путь?

Я сделал символическую ссылку, используя команду ln -s source target.

В первой попытке я использовал относительный путь, и в результате поиска в Интернете broken symbolic link...

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

5
задан 11 January 2018 в 17:25

3 ответа

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

zanna@toaster:~/playground$ mkdir linkyland anotherplace
zanna@toaster:~/playground$ cd linkyland
zanna@toaster:~/playground/linkyland$ ln -s sauce target
zanna@toaster:~/playground/linkyland$ file *
target: broken symbolic link to sauce

ln не волнует, существует ли исходный файл (поэтому, если вы сделаете опечатку в пути, он не будет жаловаться). Давайте создадим файл, на который мы хотим сослаться, и посмотрим, поможет ли это:

zanna@toaster:~/playground/linkyland$ > sauce
zanna@toaster:~/playground/linkyland$ file target
target: symbolic link to sauce

Теперь ссылка работает. Мы можем использовать только базовое имя (последний элемент пути), поскольку sauce находится в том же каталоге, что и target, поэтому target может хранить путь sauce, и этой информации достаточно, чтобы найти sauce когда нам это нужно.

zanna@toaster:~/playground/linkyland$ cd ../anotherplace
zanna@toaster:~/playground/anotherplace$ ln -s sauce target
zanna@toaster:~/playground/anotherplace$ file target
target: broken symbolic link to sauce

Эта символическая ссылка не работает, потому что здесь нет sauce. Путь sauce недостаточно информации. (С этого момента я удалил часть user@host моего приглашения для более удобного чтения, но я показываю часть, которая указывает текущий рабочий каталог, поскольку это показывает, как работают команды.) . Мы можем исправить это, используя абсолютный путь для создания символической ссылки:

~/playground/anotherplace$ rm target
~/playground/anotherplace$ ls -s /home/zanna/playground/linkyland/sauce target
~/playground/anotherplace$ file target
target: symbolic link to /home/zanna/playground/linkyland/sauce

Однако мы также можем исправить это, сделав правильный относительный путь:

~/playground/anotherplace$ rm target 
~/playground/anotherplace$ ln -s ../linkyland/sauce target
~/playground/anotherplace$ file target
target: symbolic link to ../linkyland/sauce

Итак, идея о том, что нам нужны абсолютные пути, ... просто ошибочна. Нам нужен правильный путь, абсолютный или относительный.

Если пути меняются, символические ссылки с абсолютными путями к файлам в том же каталоге ломаются, но с относительными путями нет:

~/playground/anotherplace$ cd ../linkyland
~/playground/linkyland$ ln -s /home/zanna/playground/linkyland/sauce target2
~/playground/linkyland$ cd ..
~/playground$ mv linkyland elsewhere
~/playground$ file elsewhere/target*
elsewhere/target: symbolic link to sauce
elsewhere/target2: broken symbolic link to /home/zanna/playground/linkyland/sauce

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

~/playground$ cd anotherplace 
~/playground/anotherplace$ ln -s ../elsewhere/sauce target-rel
~/playground/anotherplace$ ln -s /home/zanna/playground/elsewhere/sauce target-abs
~/playground/anotherplace$ cd ..
~/playground$ mv anotherplace ..
~/playground$ cd ..
~$ file anotherplace/*
anotherplace/target-abs: symbolic link to /home/zanna/playground/elsewhere/sauce
anotherplace/target-rel: broken symbolic link to ../elsewhere/sauce
5
ответ дан 11 January 2018 в 17:25

Символьным ссылкам не нужны абсолютные пути. Он прекрасно работает с относительными путями:

$ ls -l /usr/bin/X11
lrwxrwxrwx 1 root root 1 May 11  2017 /usr/bin/X11 -> .

Смотрите, вот символическая ссылка на относительный путь, которая прекрасно работает:

$ realpath /usr/bin/X11/yes
/usr/bin/yes
$ file /usr/bin/X11/yes
/usr/bin/X11/yes: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=add2c9ee02a98b5066d08d5ba2e79697880b2662, stripped
3
ответ дан 11 January 2018 в 17:25

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

Из официальных документов для ln:

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

Итак, главное, что нужно знать, это то, что то, что вы пишете в качестве источника/файла/пути, в основном просто помещается в файл ссылки дословно, как текст. Когда файл ссылки позже интерпретируется, этот текст пути — это место, где ваш компьютер пытается перейти к из каталога символической ссылки .

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

Моя ошибка заключалась в том, что я предполагал, что команда ln выполнит для меня какую-то умную переинтерпретацию пути, я подумал, что поскольку --relative является опцией, то если не был указан, ln преобразовал бы мой относительный путь завершения вкладки в абсолютный путь, но это так не работает.

Поиграв еще немного, я обнаружил, что опция --relative не связана с интерпретацией ссылки как относительного пути или абсолютного пути, но на самом деле, похоже, она обеспечивает поведение, которое я изначально ожидание!

Итак, теперь я пришел к пониманию, что если вы используете ln -s без --relative или -r, то что бы вы ни писали для путь/к/исходному файлу останется неизменным в файле ссылки, и вы можете использовать здесь относительный путь, но любой указанный вами путь будет интерпретироваться в контексте из каталога, в котором находится символическая ссылка. в .

Если же вы используете ln -sr, то вы можете использовать автодополнение для перехода к исходному файлу из текущего каталога, даже если вы не создание символической ссылки в этом каталоге и ln сделают некоторые умные вещи, чтобы преобразовать этот путь с вкладкой, который вы написали в команде, в тот, который действителен при интерпретации из расположение вашей символической ссылки.

Так, например:

alex@pc:/run/shm/training$ echo hello > sourcefile.txt
alex@pc:/run/shm/training$ ls
sourcefile.txt
alex@pc:/run/shm/training$ ln -s sourcefile.txt sameDirNotRelative
alex@pc:/run/shm/training$ ln -sr sourcefile.txt sameDirRelative
alex@pc:/run/shm/training$ cd ..
alex@pc:/run/shm$ ln -s training/sourcefile.txt training/oneUpNotRelative
alex@pc:/run/shm$ ln -sr training/sourcefile.txt training/oneUpRelative
alex@pc:/run/shm$ cd ..
alex@pc:/run$ ln -s shm/training/sourcefile.txt shm/training/twoUpNotRelative
alex@pc:/run$ ln -sr shm/training/sourcefile.txt shm/training/twoUpRelative
alex@pc:/run$ cd shm/training/
alex@pc:/run/shm/training$ ls -l
total 4
lrwxrwxrwx 1 alex alex 23 Jul  6 09:10 oneUpNotRelative -> training/sourcefile.txt
lrwxrwxrwx 1 alex alex 14 Jul  6 09:10 oneUpRelative -> sourcefile.txt
lrwxrwxrwx 1 alex alex 14 Jul  6 09:10 sameDirNotRelative -> sourcefile.txt
lrwxrwxrwx 1 alex alex 14 Jul  6 09:10 sameDirRelative -> sourcefile.txt
-rw-r--r-- 1 alex alex  6 Jul  6 09:08 sourcefile.txt
lrwxrwxrwx 1 alex alex 27 Jul  6 09:11 twoUpNotRelative -> shm/training/sourcefile.txt
lrwxrwxrwx 1 alex alex 14 Jul  6 09:11 twoUpRelative -> sourcefile.txt

Проверка результирующих ссылок показывает, что две из них не работают: те, что созданы без относительного флага и из-за пределов их резидентного каталога (/run/shm/training), относительный, созданный в том же каталоге training, просто работает, потому что путь действителен при переходе из резидентного каталога ссылки.

alex@pc:/run/shm/training$ file sameDirNotRelative 
sameDirNotRelative: symbolic link to sourcefile.txt
alex@pc:/run/shm/training$ file oneUpNotRelative 
oneUpNotRelative: broken symbolic link to training/sourcefile.txt
alex@pc:/run/shm/training$ file twoUpNotRelative 
twoUpNotRelative: broken symbolic link to shm/training/sourcefile.txt
3
ответ дан 5 July 2020 в 14:48

Другие вопросы по тегам:

Похожие вопросы: