Предоставляет ли какая-либо операционная система механизм (системный вызов, а не программа командной строки) для изменения имени пути, на которое ссылается символическая ссылка (символическая ссылка), кроме отмены связи старой и создания новой?
Стандарт POSIX этого не делает. В Solaris 10 этого нет. MacOS X 10.5 (Leopard) этого не делает. (Я вполне уверен, что ни AIX, ни HP-UX тоже. Судя по этому списку системных вызовов Linux, в Linux такого системного вызова также нет.)
Есть что-нибудь, что делает?
(Я ожидаю, что ответ будет «Нет».)
Поскольку доказать отрицательный результат сложно, давайте реорганизуем вопрос.
Если вы знаете, что какая-то (Unix-подобная) операционная система, еще не указанная в списке, не имеет системного вызова для перезаписи значения символической ссылки (строки, возвращаемой readlink()
) без удаления старой символической ссылки и создания новой, добавьте ее - или их - в ответ.
ln
команду (или эквивалент API), перезаписав старую ссылку? Какая у вас проблема?Ответы:
AFAIK, нет, вы не можете. Вы должны удалить его и создать заново.Фактически, вы можете перезаписать символическую ссылку и, таким образом, обновить путь, на который она ссылается:РЕДАКТИРОВАТЬ : как OP указал в комментарии, использование этой
--force
опции заставитln
выполнить системный вызовunlink()
раньшеsymlink()
. Ниже приведены результатыstrace
моей работы с Linux, подтверждающие это:Поэтому я предполагаю, что окончательный ответ - «нет».РЕДАКТИРОВАТЬ : следующее скопировано из ответа Арто Бендикена на unix.stackexchange.com, около 2016 года.
Это может действительно быть сделано атомарно с
rename(2)
, сначала создать новую символическую ссылку под временным именем , а затем аккуратно перезаписывать старый симлинк на одном дыхании. Как указано на странице руководства :В оболочке это можно сделать
mv -T
следующим образом:Вы можете использовать
strace
последнюю команду, чтобы убедиться, что она действительно используетсяrename(2)
под капотом:Обратите внимание, что в приведенном выше примере оба
mv -T
иstrace
относятся к Linux.В FreeBSD используйте
mv -h
поочередно.Примечание редактора: именно так Капистрано делал это уже много лет, начиная с ~ 2.15. См. Этот запрос на перенос .
источник
Да, ты можешь!
источник
-f
означает опция «удалить существующий пункт назначения» , прежде чем создавать новый. Итак, эта команда достигает результата, ноunlink(2)
после выполнения командыsymlink(2)
. Это не то, о чем исходный вопрос. Также обратите внимание, что принятый ответ и следующий по количеству голосов ответ используютсяln -sf
для выполнения работы, но, какstrace
показывают выходные данные, это такunlink()
иsymlink()
потому, что нет системного вызова для изменения символической ссылки.Нет необходимости явно отключать старую символическую ссылку. Ты можешь сделать это:
(или используйте эквивалентные вызовы символической ссылки и переименования). Это лучше, чем явное отключение, потому что переименование является атомарным, поэтому вы можете быть уверены, что ссылка всегда будет указывать либо на старую, либо на новую цель. Однако это не приведет к повторному использованию исходного inode.
В некоторых файловых системах цель символической ссылки сохраняется в самом inode (вместо списка блоков), если он достаточно короткий; это определяется во время его создания.
Что касается утверждения о том, что фактический владелец и группа несущественны, символическая ссылка (7) в Linux говорит, что есть случай, когда это важно:
источник
set -x -e; mkdir junk; ( cd junk; mkdir olddir newdir; ln -s olddir mylink; ls -ilR; ln -s newdir temp; ls -ilR; mv temp mylink; ls -ilR; ); rm -fr junk
. Если вы создадите файлы oldfile и newfile вместо каталогов и запустите эквивалентный сценарий (в основном меняя olddir на oldfile, newdir на newfile), то вы получите ожидаемый эффект. Всего одна дополнительная сложность! Спасибо за ответ.Просто предупреждение к правильным ответам выше:
Использование метода -f / --force создает риск потери файла, если вы перепутаете источник и цель:
Конечно, это задумано, но обычно случаются ошибки. Итак, удаление и восстановление символической ссылки - это немного больше работы, но также немного экономия:
который, по крайней мере, хранит мой файл.
источник
-f
или--force
всегда немного опасно; предполагается, что пользователь знает, о чем они. Это вдвойне смертельно, если использовать его постоянно (rm -fr …
каждый раз опасно).Разве отключение его и создание нового в любом случае не приведет к тому же результату?
источник
ln --force
команда полностью перезапишет существующую ссылку.ln (1)
, а Мэтт Б. обсуждают тот факт , чтоsymlink (2)
вовсе не поддерживает перезапись. Вы оба правы, и я бы посоветовал взглянуть на реализацию,ln (1)
чтобы получить наиболее идеальный способ выполнения процедуры отсоединения-повторного связывания.На всякий случай поможет: есть способ отредактировать символическую ссылку с помощью midnight commander (mc). Команда меню (на французском языке в моем интерфейсе MC):
который можно перевести на:
Ярлык - Cx Cs
Может, он внутренне использует
ln --force
команду, я не знаю.Теперь я пытаюсь найти способ редактировать сразу множество символических ссылок (вот как я сюда попал).
источник
unlink()
которым следует asymlink()
, просто потому, что это то, что предоставляют Unix-подобные системы.Технически нет встроенной команды для редактирования существующей символической ссылки. Этого легко добиться с помощью нескольких коротких команд.
Вот небольшая функция bash / zsh, которую я написал для обновления существующей символической ссылки:
источник
unlink()
иsymlink()
с новым значением, что и происходит за кулисами с вашим кодом. Лично я бы попросил, чтобы функция настаивала на двух (или, возможно, кратном двух) аргументах и брала под залог, если вызов был неправильным. Однако это особая точка зрения.