So I created a symbolic link:
ln -s /location/to/link linkname
Now I want to change the location that the symlink links to. How do I do that? Is there a way to do it without deleting it first?
So I created a symbolic link:
ln -s /location/to/link linkname
Now I want to change the location that the symlink links to. How do I do that? Is there a way to do it without deleting it first?
You could create the new link with a different name, then move it to replace the old link.
ln -s /location/to/link linkname
Later
ln -s /location/to/link2 newlink
mv newlink linkname
If newlink
and linkname
are on the same physical device the mv
should be atomic.
mv newlink linkname
caused the newlink
file to be deleted, but didn't overwrite the linkname
file? Did it do this silently? That seems extremely mysterious. –
Affected mv newlink linkname
will move your newlink
into linkname
if they are directories. So this method is not 100% perfect. –
Internee mv -T
instead of plain mv
? –
Imputable Try ln -sf new_destination linkname
.
Just change the symlink target:
# ln -sfT /path/to/new/target linkname
This is an instant, atomic change.
T
option? I don't have in my MacOS –
Vacancy -T, --no-target-directory treat LINK_NAME as a normal file always
you can brew install coreutils
and access the GNU versions with a g
prefix, like gln
if you want the GNU versions on macOS. saves a lot of headache when there are subtle differences like this. –
Philippic -n
can also work, and has the benefit of existing both on GNU ln
and MacOS's ln
. –
Uncrowned If the symlink targets are directories, you need to add the -T
flag to the mv
command, otherwise it moves the new symlink in to the target directory of the old symlink.
Example of atomically switching a website to a new version:
Original setup - website is stored in www1
directory, vhost pointing at www
symlink:
ln -s www1 www
Browse to website, see old version.
Put new website files in new www2
directory.
Set up new symlink to new website:
ln -s www_new www2
Move www
symlink to directory of new website:
mv -T www_new www
Browse to website, see new version immediately.
ln -sf new_destination linkname
–
Tarrsus On OS X, the man page for ln says you can do it like this:
ln -shf /location/to/link link name
From the man page:
The options are as follows:
-F If the target file already exists and is a directory, then remove it so that the link may occur. The -F
option should be used with either -f or -i options. If none is specified, -f is implied. The -F option is
a no-op unless -s option is specified.
-h If the target_file or target_dir is a symbolic link, do not follow it. This is most useful with the -f
option, to replace a symlink which may point to a directory.
-f If the target file already exists, then unlink it so that the link may occur. (The -f option overrides any
previous -i options.)
-i Cause ln to write a prompt to standard error if the target file exists. If the response from the standard
input begins with the character `y' or `Y', then unlink the target file so that the link may occur. Other-
wise, do not attempt the link. (The -i option overrides any previous -f options.)
-n Same as -h, for compatibility with other ln implementations.
-s Create a symbolic link.
-v Cause ln to be verbose, showing files as they are processed.
For directories, you want to do: ln -sfT /location/to/new/target old_linkname
No. The symlink
system call will return EEXIST
if newpath already exists. You can only link from a new node in the filesystem. What's the requirement here? If you're worried about a race due to the non-atomicity of the unlink/symlink calls, then you might want to rethink the architecture a little to provide synchronization elsewhere. There have been some scary security bugs introduced by this kind of thing.
As others have mentioned, you basically have to delete the symlink first, either manually or by passing the -f
flag to the ln
utility.
Years ago, I had to make small edits to symlinks pretty frequently, so I wrote a simple readline-based utility (edln
) to make this less annoying. In case anyone else finds it useful, I've put it online at https://github.com/jjlin/edln/.
edln
will display the original symlink target; you can then use the arrow keys, or standard readline keystrokes (M-b
, M-f
, C-d
, etc.) to move around and edit the target.
read
built-in's readline support: read -e -p 'New: ' -i "$(readlink -- "$1")" lnk
–
Gonad (touch 'a b'; IFS= read -e -p 'New: ' -i ./ lnk; echo ":$lnk:"; ls "$lnk")
seems to work for me, read -e
undoes the escapes; there's just a trailing whitespace after pressing <TAB> the user must delete –
Gonad -r
to read
-- with all its implications. Then tab-completion adds escapes, which are undone by read
's default behavior –
Gonad Chain the commands like this:
rm currentlink && ln -s /path/to/link currentlink
The first command removes the existing one and the 2nd immediately creates it again.
Just googled, found no good answer and had to solve myself:
ln -f -s -T `readlink SomeLibrary | sed 's/version.old/version.new/'` SomeLibrary
Editing by definition means not recreating from scratch but changing partly. Any answer requiring to memorize a path, maybe long or with weird symbols, is definitely bad.
© 2022 - 2024 — McMap. All rights reserved.