AFAIK, não, você não pode. Você precisa removê-lo e recriá-lo. Na verdade, você pode sobrescrever um link simbólico e, assim, atualizar o nome do caminho mencionado por ele:
$ 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 : Como o OP apontou em um comentário, o uso da --force
opção fará ln
uma chamada de sistema para unlink()
antes symlink()
. Abaixo, a saída da strace
minha caixa linux provando:
$ 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
Então eu acho que a resposta final é "não".
EDIT : O seguinte é copiado da resposta de Arto Bendiken em unix.stackexchange.com, por volta de 2016.
Na verdade, isso pode ser feito atomicamente rename(2)
, criando primeiro o novo link simbólico com um nome temporário e depois substituindo de maneira limpa o link simbólico antigo de uma só vez. Como a página do manual afirma:
Se newpath se referir a um link simbólico, o link será substituído.
No shell, você faria isso da mv -T
seguinte maneira:
$ mkdir a b
$ ln -s a z
$ ln -s b z.new
$ mv -T z.new z
Você pode strace
executar esse último comando para garantir que ele esteja realmente sendo usado por rename(2)
baixo do capô:
$ 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
Observe que, acima, ambos mv -T
e strace
são específicos do Linux.
No FreeBSD, use mv -h
alternadamente.
Nota do editor: É assim que Capistrano faz isso há anos, desde ~ 2.15. Veja esta solicitação de recebimento .
ln
comando (ou a API equiavalente) substituindo o link antigo? Qual problema você está tendo?