When you have a link like:
link -> foo/bar
and want to change it to:
link -> new/target
There are two cases to consider:
foo/bar
is not a directory or doesn't exist or you don't have search access to foo
. Then
ln -s new/target link
will fail because link
already exists, but you can overcome that by using the standard:
ln -fs new/target link
foo/bar
is a directory (and you have search permission to foo
to be able to determine that foo/bar
is a directory). In that case, when you do:
ln -s new/target link
or
ln -fs new/target link
That's understood as creating a new target
symlink inside the link
directory (link
is a directory because it's a symlink to the foo/bar
directory). So you'll actually create a:
foo/bar/target -> new/target
To overcome that, GNU ln
has a -T
option for the link name to always be considered as link name, and not as a directory to create the link(s) in. So, with GNU ln
:
ln -fsT new/target link
will work. Like before, it will remove the original link
symlink and create it anew with new/target
as the target (and the process' euid and egid as the owner).
GNU ln
also has a -n
option. It works like -T
except when link
is actually a real directory in which case it will still create the symlink inside that directory (instead of failing with an error).
Portably, your best option is to remove the link first and then recreate it:
rm -f link && ln -s new/target link
On most systems, permissions on symlinks are ignored and generally fixed to rwxrwxrwx
.
On systems where symlink permissions matter (like OS/X where you need read permission to a symlink to be able to resolve its target), there's generally a way to change them (chmod -h
on OS/X).
Ownership, while like above not relevant for access to the file pointed to by the symlink on most systems, can have some other relevance wrt the t
bit of the parent directory or quotas...) and there's a standard command to change it:
chown -h user[:group] the-link
chgrp -h group the-link