AFAIK, нет, вы не можете. Вы должны удалить его и создать заново. Фактически, вы можете перезаписать символическую ссылку и, таким образом, обновить путь, на который она ссылается:
$ ln -s .bashrc test
$ ls -al test
lrwxrwxrwx 1 pascal pascal 7 2009-09-23 17:12 test -> .bashrc
$ ln -s .profile test
ln: creating symbolic link `test': File exists
$ ln -s -f .profile test
$ ls -al test
lrwxrwxrwx 1 pascal pascal 8 2009-09-23 17:12 test -> .profile
РЕДАКТИРОВАТЬ : как OP указал в комментарии, использование этой --force
опции заставит ln
выполнить системный вызов unlink()
раньше symlink()
. Ниже приведены результаты strace
моей работы с Linux, подтверждающие это:
$ strace -o /tmp/output.txt ln -s -f .bash_aliases test
$ grep -C3 ^unlink /tmp/output.txt
lstat64("test", {st_mode=S_IFLNK|0777, st_size=7, ...}) = 0
stat64(".bash_aliases", {st_mode=S_IFREG|0644, st_size=2043, ...}) = 0
symlink(".bash_aliases", "test") = -1 EEXIST (File exists)
unlink("test") = 0
symlink(".bash_aliases", "test") = 0
close(0) = 0
close(1) = 0
Поэтому я предполагаю, что окончательный ответ - «нет».
РЕДАКТИРОВАТЬ : следующее скопировано из ответа Арто Бендикена на unix.stackexchange.com, около 2016 года.
Это может действительно быть сделано атомарно с rename(2)
, сначала создать новую символическую ссылку под временным именем , а затем аккуратно перезаписывать старый симлинк на одном дыхании. Как указано на странице руководства :
Если newpath ссылается на символическую ссылку, ссылка будет перезаписана.
В оболочке это можно сделать mv -T
следующим образом:
$ mkdir a b
$ ln -s a z
$ ln -s b z.new
$ mv -T z.new z
Вы можете использовать strace
последнюю команду, чтобы убедиться, что она действительно используется rename(2)
под капотом:
$ strace mv -T z.new z
lstat64("z.new", {st_mode=S_IFLNK|0777, st_size=1, ...}) = 0
lstat64("z", {st_mode=S_IFLNK|0777, st_size=1, ...}) = 0
rename("z.new", "z") = 0
Обратите внимание, что в приведенном выше примере оба mv -T
и strace
относятся к Linux.
В FreeBSD используйте mv -h
поочередно.
Примечание редактора: именно так Капистрано делал это уже много лет, начиная с ~ 2.15. См. Этот запрос на перенос .
ln
команду (или эквивалент API), перезаписав старую ссылку? Какая у вас проблема?