Как переопределить / обновить символическую ссылку?

188

Я пытаюсь использовать символические ссылки. Я немного почитал и нашел следующие команды:

Creation -> ln -s {/path/to/file-name} {link-name}
Update -> ln -sfn {/path/to/file-name} {link-name}
Deletion -> rm {link-name}

Создания и удаления работают нормально. Но обновления не работают. После выполнения этой команды символическая ссылка становится недействительной.

Я прочитал кое-что, что невозможно обновить / переопределить символическую ссылку. Так что в сети есть противоречивая информация. Кто прав? Если символическая ссылка может быть обновлена ​​/ переопределена, как я могу добиться этого?

Обновить

Вот моя структура каталогов:

~/scripts/test/
~/scripts/test/remote_loc/
~/scripts/test/remote_loc/site1/
~/scripts/test/remote_loc/site1/stuff1.txt
~/scripts/test/remote_loc/site2/
~/scripts/test/remote_loc/site2/stuff2.txt
~/scripts/test/remote_loc/site2/
~/scripts/test/remote_loc/site3/stuff3.txt

От ~/scripts/test/, когда я выполняю:

ln -s /remote_loc/site1 test_link

a test_linkсоздан, и я могу ls -lэто сделать, но он кажется сломанным (вопреки тому, что я сказал выше в своем вопросе).

Как выполнить ссылку на несколько каталогов?

Жером Верстринг
источник
1
Я рекомендую использовать unlinkвместо rm. При этом unlinkвы никогда не рискуете потерять какие-либо файлы в исходном каталоге, случайно используя неправильные ключи.
Jpsy
Вы используете ведущий / в вашей команде
Джейми Кук
@jpsy ваш совет по поводу unlink был бы очень хорош, если бы это было правдой . Попробуйте коснуться zzzz; отменить ссылку zzzz. (unlink звонки, unlink так же, как rm, но без модных опций и без рекурсии).
Ctrl-Alt-Delor
Зачем использовать -n? (может быть проблема). Кроме того, если ваш пер поддерживает -tзатем использовать его для этих случаев, и -Tили destination/для других случаев.
Ctrl-Alt-Delor

Ответы:

150

Использование -fс lnперезапишет любую ссылку, которая уже была там, так что, если у вас есть правильные разрешения, она должна работать ... Это всегда работает для меня. Какую операционную систему ты используешь?

Sirch
источник
Я обновил свой вопрос с дополнительной информацией по моей проблеме.
Жером Верстринг
Я под Linux.
Жером Верстринг
2
Если вы переключите lnпараметры, как я склонен, -fуничтожит ли ваш файл существующие файлы (ссылки цели)? В любом случае, у нас есть -iпараметр (который будет запрашивать у пользователя перезапись), если вы хотите немного безопасности.
Palswim
2
@palswim Этот пост SO подразумевает, что это безопасно, потому что -fтолько звонки unlink()и link()под капотом: stackoverflow.com/a/1466570/157385 . Хотел бы я просто вспомнить правильный порядок!
Майк Брански,
4
Не работает. Потребности -n. Смотрите принятый ответ.
Шон Уэлч
119

Хорошо, я нашел, где моя ошибка: нельзя ставить первое /в пути.

Другими словами, команды в моих вопросах должны быть:

Creation -> ln -s {path/to/file-name} {link-name}
Update -> ln -sfn {path/to/file-name} {link-name}

вместо

Creation -> ln -s {/path/to/file-name} {link-name}
Update -> ln -sfn {/path/to/file-name} {link-name}

рассматривая мой случай.

Жером Верстринг
источник
22
Для некоторой дополнительной информации о том, почему это так, различия в том, что одно - это relativeпуть (без ведущего /), а другое - это absoluteпуть (с ведущим /). Если вы управляете системой Linux, КРИТИЧЕСКИ вы понимаете разницу. Например, разница между rm -rf ./*и rm -rf /.*решает, сохранить ли вам работу или нет :)
Safado
5
Это не отвечает на вопрос «как обновить / переопределить символьную ссылку»
Sirch
Строка ln -sfn {путь / к / имя-файла} {имя-ссылки} делает.
Жером Верстринг
6
-n (--no-dereference) заставляет его обрабатывать {имя ссылки} как обычный файл, а не переходить по ссылке. Учитывая, что вам нужно работать по этой ссылке, а не переходить по ней, вы должны использовать эту опцию.
Feldoh
1
Этот ответ должен быть выделен ответом с -nпараметром для замены символьной ссылки.
Ник Цай
12

Первая проблема:

Цитирую вас:

Создания и удаления работают нормально. Но обновления не работают. После выполнения этой команды символическая ссылка становится недействительной.

Проблема с заданной структурой каталогов:

~ / scripts / test / ~ / scripts / test / remote_loc / ~ / scripts / test / remote_loc / site1 / ~ / scripts / test / remote_loc / site1 / stuff1.txt ~ / scripts / test / remote_loc / site2 / ~ / scripts /test/remote_loc/site2/stuff2.txt ~ / scripts / test / remote_loc / site2 / ~ / scripts / test / remote_loc / site3 / stuff3.txt

и с помощью команды:

ln -s /remote_loc/site1 test_link

Это создает символическую ссылку в вашем $ PWD или текущем рабочем каталоге, которая указывает на несуществующий файл из /, или root, в / remote_loc / site1

Если ваш PWD находится в ~ / scripts /, то вы должны были использовать это:

ln -s remote_loc/site1 test_link

иначе вы могли бы использовать полный абсолютный путь, например:

ln -s /home/yourusername/remote_loc/site1 test_link

Второй выпуск:

Цитирую вас:

Я прочитал кое-что, что невозможно обновить / переопределить символическую ссылку. Так что в сети есть противоречивая информация. Кто прав? Если символическая ссылка может быть обновлена ​​/ переопределена, как я могу добиться этого?

Отвечая на ваш вопрос «Кто прав», я не уверен, что именно вы прочитали или как это поняли. Но следующее должно помочь прояснить ситуацию:

  1. Что можно обновить и
  2. Что не может быть обновлено без использования соответствующих переключателей.


Обновление символических ссылок с целями, которые не являются каталогами.

ln -sf:
-f или --force удалить существующие файлы назначения. Используется для обновления цели или места назначения ссылки.

Пример:

 ln -sf /tmp/test /tmp/test.link; ls -go /tmp |grep test
 -rw-r--r-- 1    0 Jun  8 17:19 test
 lrwxrwxrwx 1    9 Jun  8 17:27 test.link -> /tmp/test

Но, как вы можете видеть, он даст абсолютный путь, если в lnаргументах есть абсолютные пути . Указание полного пути необходимо, когда текущий рабочий каталог отличается от родительского каталога ссылки.


Относительные пути:

ln -sfr:
-r или --relative создает символические ссылки относительно местоположения ссылки.

Пример:

ln -sfr /tmp/test  /tmp/test.link  ; ls -go /tmp| grep test
-rw-r--r-- 1    0 Jun  8 17:19 test
lrwxrwxrwx 1    4 Jun  8 17:27 test.link -> test

Но обновление ссылки на каталог не будет работать, если целью является каталог.

Пример:

ln -sf /tmp/testdir  /tmp/testdir.link  ; ls -go /tmp  |grep testdir
drwxr-xr-x 2 4096 Jun  8 17:48 testdir
lrwxrwxrwx 1    7 Jun  8 17:47 testdir.link -> testdir

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


Обновить ссылки на каталоги:

ln -sfrn:
-n или --no-dereference обрабатывает LINK_NAME как обычный файл, если это символическая ссылка на каталог.

Пример:

ln -sfn /tmp/testdir /tmp/testdir.link; ls -go /tmp| grep testdir
drwxr-xr-x 2 4096 Jun  8 17:48 testdir
lrwxrwxrwx 1   12 Jun  8 17:48 testdir.link -> /tmp/testdir

В отличие от:

ln -sfnr /tmp/testdir /tmp/testdir.link; ls -go /tmp| grep testdir
drwxr-xr-x 2 4096 Jun  8 17:48 testdir
lrwxrwxrwx 1    7 Jun  8 17:48 testdir.link -> testdir
Кит Рейнольдс
источник
6
$ touch test1 test2
$ ln -sf test2 test1
$ ls -l test[12]
lrwxrwxrwx 1 user01 user01 5 2012-05-17 14:41 test1 -> test2
-rw-r--r-- 1 user01 user01 0 2012-05-17 14:41 test2
jirib
источник
Когда я выполняю тесты с одним уровнем каталогов, это работает, но я пытаюсь использовать многоуровневые каталоги, и это не работает. Я обновил свой вопрос.
Жером Верстринг