Никакое значение фиксированной длины никогда не может гарантировать, что было на 100% уникально (просто называют его достаточно раз, плюс-минус окончание вселенной;-p) - но это может быть очень, очень, очень вряд ли для дублирования.
Знаете, нет, вы не можете. Вы должны удалить его и создать заново. Фактически, вы можете перезаписать символическую ссылку и, таким образом, обновить путь, на который она ссылается:
$ 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
EDIT : как 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
Итак, я предполагаю, что окончательный ответ - «нет».
РЕДАКТИРОВАТЬ : Следующее скопировано из Arto Ответ Бендикена на 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. См. этот запрос на перенос .
Как указано на странице руководства :Если 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. См. этот запрос на перенос .
Как указано на странице руководства :Если 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. См. этот запрос на перенос .
$ 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. См. этот запрос на перенос .
$ 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 -s newtarget temp
mv temp mylink
(или использовать эквивалентные вызовы символической ссылки и переименования). Это лучше, чем явное отключение, потому что переименование является атомарным, поэтому вы можете быть уверены, что ссылка всегда будет указывать либо на старую, либо на новую цель. Однако при этом не будет повторно использоваться исходный индексный дескриптор.
В некоторых файловых системах цель символической ссылки сохраняется в самом индексном дескрипторе (вместо списка блоков), если он достаточно короткий; это определяется во время создания.
Что касается утверждения, что фактический владелец и группа не имеют значения, символическая ссылка (7) в Linux говорит, что есть случай, когда это имеет значение:
] Владелец и группу существующей символической ссылки можно изменить с помощью lchown (2). Единственный раз, когда право собственности на символическую ссылку имеет значение, это когда ссылка удаляется или переименовывается в каталоге с прикрепленным установлен бит (см. stat (2)).
Временные метки последнего доступа и последнего изменения символьной ссылки могут быть изменено с помощью utimensat (2) или lutimes (3).
В Linux разрешения символьной ссылки не используются ни в каких операциях; разрешения всегда 0777 (чтение, запись и выполнение для всех пользователей категории) и не могут быть изменены.
Разве отключение и создание новой связи в любом случае не приведет к тому же результату?