Чи є ціль symlink відносно батьківського каталогу призначення, і якщо так, то чому?


14

У мене така файлова структура:

build/
client/
  –> index.js

І коли я намагаюся створити символьне посилання під назвою "client" всередині каталогу збирання, яке посилається на клієнтський каталог у cwd, як так

// Fails
$ pwd
/home/user/
$ ln -s client build/client 
$ stat build/client/index.js
stat: build/client/index.js: stat: Too many levels of symbolic links

Я отримую помилку ELOOP, відображену вище. Коли я змінюю цільовий шлях, щоб він був відносно шляху призначення, все добре:

// Works
$ pwd
/home/user/
$ ln -s ../client build/client 
$ stat build/client/index.js
stat: <outputs file stats>

Це цільова поведінка і поясніть, будь ласка, чому ...


це, мабуть, має відношення до ефекту, який використовує ../ використовувати абсолютний шлях для оголошення шляху замість відносного шляху. хороша умова - завжди використовувати абсолютний шлях
Ківі

Я погоджуюся з найкращою практикою, оскільки я завжди використовував абсолютні шляхи як для цілі, так і для місця призначення. Однак на сторінках чоловіка зазначено, що відносні шляхи можна використовувати для обох ...
jibsales

Відповіді:


13

Для того, що не працює, якщо ми подивимось на ls -lрезультат, то отримаємо наступне:

[sparticvs@sparta test]$ ls -l build/
total 0
lrwxrwxrwx. 1 sparticvs sparticvs 6 Dec 17 16:08 client -> client

Тепер зрозуміти, що тут відбувається. Давайте розглянемо команду, яку ви викликали:

ln -s client build/client

За інформацією Man Page, для цього формату є два можливі відповідники

SYNOPSIS
       ln [OPTION]... [-T] TARGET LINK_NAME   (1st form)
       ln [OPTION]... TARGET... DIRECTORY     (3rd form)

Він буде відповідати на першій формі (з моменту її першого). Тепер, "ім'я цілі" або clientу вашому випадку, можуть бути (згідно з повним lnпосібником) довільними рядками. Вони не повинні вирішувати що-небудь прямо зараз, але можуть вирішити щось у майбутньому. Те, що ви створюєте за допомогою виклику, - це "звисаюче символьне посилання", і система не заважає вам створювати їх.

Тепер ваше друге виклик ln -s ../client build/client- це те, що називається "відносне символьне посилання" (як ви зазначили у власній публікації). Існує другий тип, і це "абсолютна симпосилання", яку можна було б викликати шляхомln -s /home/user/client build/client .

Це не помилка. Згідно з посібником, в якому зазначено:

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

- від info coreutils 'ln invocation'

При цьому ви ОБОВ'ЯЗКИ використовувати або відносний, або абсолютний шлях до цілі.


5

Це дійсно призначена поведінка. На ln(1)чоловіковій сторінці:

Символічні посилання можуть містити довільний текст; якщо пізніше вирішено, відносне посилання інтерпретується стосовно його батьківського каталогу.

Щодо цього, уявіть собі, якби замість цього посилання інтерпретувались відносно джерела, а не від місця призначення. Пізніше розв’язуючи його, вам потрібно буде знати, яким був ваш CWD, коли ви його створили, що є безглуздим, не кажучи вже про неможливим.

Більше того, таким чином ви отримуєте акуратний та компактний метод створення структури каталогів скелетів, який можна скидати куди завгодно у дерево каталогів, не порушуючи символьні посилання.

Щоб привести вам приклад того, що я маю на увазі, скажімо, ви працюєте над проектом, і у вас створена ціла структура каталогів так:

$ ls -1 /home/you/project
thingummies/
widgets/
wizardry/

Тепер припустимо, що ви хотіли створити симпосилання widgets/досередини wizardry/. У вас є два варіанти:

$ ln -s /home/you/project/widgets /home/you/project/wizardry

або

$ ln -s ../widgets /home/you/project/wizardry

Якщо потім спробувати переміститися /home/you/projectкуди-небудь ще, символьне посилання, створене з першою формою, розірветься, оскільки воно шукає /home/you/project/widgets. Друга форма збереже функцію символьного посилання, оскільки вона шукає ../widgets відносно місця, в якому знаходиться, незалежно від того, де це місце може бути в дереві каталогів.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.