Зробіть символічне посилання на відносну назву шляху


64

Я можу це зробити:

$ pwd
/home/beau
$ ln -s /home/beau/foo/bar.txt /home/beau/bar.txt
$ readlink -f bar.txt
/home/beau/foo/bar.txt

Але я хотів би це зробити:

$ pwd
/home/beau
$ cd foo
$ ln -s bar.txt /home/beau/bar.txt
$ readlink -f /home/beau/bar.txt
/home/beau/foo/bar.txt

Чи можливо це? Чи можу я якось вирішити відносне ім'я шляху та передати його ln?


Але в чому полягає проблема, яка б була вирішена описаною поведінкою?
forcefsck

Ну, скажімо, ви пропонуєте для завантаження стиснуту папку і хочете дати інструкції, які можна вставити з копією, як символізувати деякі файли папки.
Хамфрі Богарт

2
ln -s $(pwd)/bar.txt ~/або включити сценарій встановлення.
forcefsck

2
посилання зберігає фактично ім'я, яке ви використовуєте в командному рядку. Дозвіл цього імені до файлу робиться відносно місця посилання. Вам доведеться скористатисяln -s foo/bar.txt /home/beau/bar.txt
pqnet

Відповіді:


62

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

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

Ви можете зробити:

$ pwd
/home/beau
$ ln -s foo/bar.txt bar.txt
$ readlink -f /home/beau/bar.txt
/home/beau/foo/bar.txt

Або для цього важливо:

$ cd foo
$ ln -s foo/bar.txt ../bar.txt

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


2
Приємно сказано. Ви відповіли на це, поки я набирав власну відповідь. :)
Шадур

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

"цей рядок розуміється як відносний шлях до батьківського каталогу симпосилання" - це пояснює все!
Bojan Komazec

24

Якщо ви використовуєте новіші Coreutils (я використовую coreutils-8.22-11), у нього є можливість зробити це:

ln --help | grep relative

вміє містити довільний текст; якщо пізніше вирішено, відносна посилання - -r, - відносна створення символічних посилань щодо місця розташування посилання

Наприклад:

$ mkdir /tmp/test
$ touch /tmp/test/to
$ ln -rs /tmp/test/to /tmp/test/from
$ ls -l /tmp/test/from
    lrwxrwxrwx 1 ptr ptr 4 aug   25 17.02 /tmp/test/to -> from

Гм, мені здається, такого варіанту немає -r. Однак за допомогою Mac.
ivkremer

1
@ivkremer, здається, цей варіант доступний, оскільки coreutils> = 8.16 (джерело: superuser.com/a/837935/403979 )
DJCrashdummy

Використовуючи відносний прапор, здавалося, вияснити проблеми "занадто багато рівнів символічних посилань", які я відчував.
Vix

12

Вибач, ні. Символічні посилання відносяться до місця, в якому знаходиться посилання, а не до місця, в якому ви були, коли ви створювали посилання. Існує кілька вагомих причин такої поведінки, більшість з яких передбачає встановлення віддалених файлових систем.


7

Існує зручна маленька утиліта, яку називають symlinks(спочатку Марк Лордс, зараз її підтримує Дж. Брандт Баклі), яка присутня у багатьох дистрибутивах Linux.

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

symlinks -c /path/to/directory

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

mkdir ../tmp
mv link-to-relativize ../tmp
symlinks ../tmp
mv ../tmp/* .
rmdir ../tmp

Дякую. символьні посилання, доступні на github . Підтримує Дж. Брандт Баклі. v1.4.3 .
Євгеній Верещагін

3

Ви можете спробувати:

ln -s `pwd`/bar.txt /home/beau/bar.txt

Але це робить символічне посилання на абсолютне ім'я шляху. У вашому текстовому запитанні задається відносне ім'я шляху ...

Зазвичай відносне ім'я шляху - це те, що ви хочете, і те, що ln -sдає вам. Я думаю, що ти хочеш:

cd /home/beau
ln -s foo/bar.txt bar.txt

1

Оскільки найбільш поширені оболонки розширюють шляхи, для створення відносної симпосилання слід вказати "вихідний шлях".

Також -sпараметр означає --symbolic. lnстворює жорсткі посилання за замовчуванням.

$ ln -s '../../relative_path' path
$ ls -al path

lrwxrwxrwx 1 empjustine empjustine 19 Aug  6 01:38 path -> ../../relative/path

0

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

ln -s `pwd`/bar.txt ~/bar.txt

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

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