Сделать символическую ссылку на относительный путь

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), но в то время, когда символическая ссылка используется и разрешается, эта строка понимается как относительный путь к родительский каталог символической ссылки (когда он не начинается с /).

penguin359
источник
2
Красиво сказано. Вы ответили на это, когда я печатал свой собственный ответ. :)
Шадур
У меня просто был немного другой вопрос - и это отвечает на него отлично. Я хотел знать, как ссылаться на домашний каталог в символической ссылке, чтобы он работал, когда я передавал его от одного пользователя другому. Я не был уверен ~, сработает ли что-то подобное .
Джо
«эта строка понимается как относительный путь к родительскому каталогу символической ссылки» - это все объясняет!
Боян Комазец
24

Если вы используете более новые coreutils (я использую coreutils-8.22-11), у него есть возможность сделать это:

ln --help | grep relative

может содержать произвольный текст; если разрешено позже, относительная ссылка - -r, --relative создать символические ссылки относительно расположения ссылки

Например:

$ 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
PTR
источник
Хм, для меня, кажется, нет такой возможности -r. Используя Mac, хотя.
ivkremer
1
@ivkremer, кажется, эта опция доступна с coreutils> = 8.16 (источник: superuser.com/a/837935/403979 )
DJCrashdummy
Использование относительного флага, казалось, прояснило проблемы «слишком большого количества символических ссылок», которые я испытывал.
Vix
12

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

Shadur
источник
7

Есть удобная небольшая утилита под названием symlinks(изначально Mark Lords, теперь поддерживаемая J. Brandt Buckley), присутствующая во многих дистрибутивах 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
MattBianco
источник
1

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

Также -sпараметр означает --symbolic. lnсоздает жесткие ссылки по умолчанию.

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

lrwxrwxrwx 1 empjustine empjustine 19 Aug  6 01:38 path -> ../../relative/path
emp.justine
источник
0

Если вы уверены, что у вас нет шансов изменить точки монтирования, вы можете добиться того, что вы пытаетесь сделать, в оболочке bash, например:

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

Это предполагает, что вы находитесь в целевом каталоге при создании символической ссылки.

mreff555
источник