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

2469
nettux443

У меня есть два каталога в моем доме: ~/dir1и ~/dir2с файлом в первом: ~/dir1/file.txtесть ли какой-нибудь способ, которым я могу сделать символическую ссылку на него, ~/dir2не переходя к, ~/и если нет, то почему это так?

Я пытался ~/запустить:

$ ln -s ./dir1/file.txt ./dir2/file.txt 

но, как я и ожидал, это приводит к тому, что результирующая символическая ссылка эффективно указывает на то, ~/dir1/dir2/file.txtчто имеет смысл, но не то, что я на самом деле хочу.

Я также попробовал:

$ ln -s ./dir1/file.txt ../dir2/file.txt 

Который возвращает:

ln: failed to create symbolic link `../dir2/file.txt': No such file or directory 

Я ожидаю, что это просто создать символическую ссылку, ~/dir2/file.txtуказывающую на~/../dir1/file.txt

Поэтому я полагаю, что мой настоящий вопрос заключается в следующем: могу ли я заставить lnсоздать символическую ссылку на файл, который, по его мнению, не существует?

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

pushd dir2/ && ln -s ../dir1/file.txt && popd 

или в Python (это самое близкое к тому, что я хочу):

echo "import os; os.symlink('../dir1/file.txt', './dir2/file.txt')" | python 
1

2 ответа на вопрос

2

Ваш вопрос немного запутанный.

  1. Вы спросили: «Могу ли я сделать символическую ссылку на него из ~/dir1[...]?» Я полагаю, вы имели в виду "от ~/dir2", основываясь на остальной части вашего поста?

  2. Ваша первая команда

    $ ln -s ./dir1/file.txt ./dir2/file.txt

    не делает то, что вы думаете, что делает. Предполагая, что вы все еще находитесь в своем домашнем каталоге, приведенная выше команда создает символическую ссылку, чей собственный путь ~/dir2/file.txt, и эта символическая ссылка указывает буквально на путь ./dir1/file.txt. Поскольку указанная символическая ссылка находится в каталоге ~/dir2, такой целевой путь разрешается в ~/dir2/./dir1/file.txt, который в дальнейшем разрешается ~/dir2/dir1/file.txt(вероятно, не существует, а не то, что вам нужно). Поэтому я сомневаюсь, почему вы сказали, что это решает ~/dir1/dir2/file.txt.

  3. Ваша вторая команда не выполняется, потому что нет директории ../dir2для вставки символической ссылки, и именно это означало сообщение об ошибке.

  4. Чтобы ответить на ваш вопрос, да. ОС не заботится о том, указывает ли ваша символическая ссылка на путь без действительного объекта файловой системы.

Вероятно, то, что вы действительно хотите, это что-то вроде

ln -s ../dir1/file.txt ./dir2/file.txt 

Похоже? Эта команда создает символическую ссылку, чей собственный путь ./dir2/file.txtи ее цель - буквальный относительный путь ../dir1/file.txt. Последний, абсолютный путь, на который указывает символическая ссылка, - это ~/dir2/../dir1/file.txt, который разрешает в ~/dir1/file.txt.

Обратите внимание, что этот ~символ является расширяемым символом оболочки, который расширяется до абсолютного пути вашего домашнего каталога. ~-expansion не является частью разрешения пути ОС.

Предлагаемое чтение

Linux страницы руководства по path_resolution(7), symlink(7), ln(1)и ln(1p).

редактировать

Разъяснения и рекомендуемое чтение.

Я понимаю, почему моя первая команда не работает, что я не ожидал работать, но я решил попробовать. Мне кажется, что вторая команда сработает, если я заставлю ее создать ссылку. Обратите внимание, что предложенные вами аргументы команды неверны. `` `` ln -s / path / to / file / path / to / new / link```` написанная вами команда пытается создать ссылку `` `` ~ ~ / dir1 / file.txt`` `` указывая на `` `` ~ / dir2 / file.txt```` (в обратном направлении !!) :) nettux443 10 лет назад 0
см. мой отредактированный вопрос для более подробной информации о том, чего я пытаюсь достичь. nettux443 10 лет назад 0
1
terdon

Вы можете сделать любой из

  1. Используйте абсолютные пути

    $ ln -s ~/dir1/file.txt ~/dir2 $ readlink dir2/file.txt  /home/terdon/dir1/file.txt 
  2. Используйте правильные относительные пути

    $ ln -s ../dir1/file.txt dir2/ $ readlink dir2/file.txt  ../dir1/file.txt 

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

Спасибо за Ваш ответ. Ваше первое предложение будет работать, если у меня были абсолютные пути, но я особенно интересовался относительными путями. Ваше второе предложение является синонимом моей второй попытки (отсутствует имя файла назначения), но я получил ошибку «файл не найден» (см. Выше) в аргументе * first *. Могу я спросить, какой дистрибутив Linux вы используете? nettux443 10 лет назад 0
@ nettux443 да, это странно. Я нахожусь на LMDE (в основном тестирование Debian) и bash `4.2.45`. Обратите внимание, что мое второе предложение не совпадает с вашим. Вы использовали `. / Dir`, а я использую` ../ dir`. Идея заключается в том, что путь должен быть относительно цели. Если вы хотите включить имя ссылки, используйте `ln -s ../dir1/file.txt ~ / dir2 / foo`, которая все еще будет работать. Это также будет работать независимо от того, где вы находитесь. Я только что попробовал описанное выше в `/ etc`, и он правильно создал файл в` ~ / dir2 / foo`, указывающий на `~ / dir1 / file.txt`. terdon 10 лет назад 0
@ nettux443 нет, `ln` только проверяет, существует ли созданный файл. Ваша задача - убедиться, что цель реальна. Это не даст ошибки, например: `ln -s / fruble / bargle / bob / tmp / foo`, он с радостью и безмолвно создаст неработающую ссылку. terdon 10 лет назад 0
Извините, вы правы, мой второй ответ не совпадает с вашим предложением. В этом и заключается проблема. Ваше предложение - это то, что я * хотел * попробовать ... надеюсь, больше не совершу эту ошибку! nettux443 10 лет назад 0
@ nettux443 lol, случается с лучшими из нас :) terdon 10 лет назад 0

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