AFAIK, nein, das kannst du nicht. Sie müssen es entfernen und neu erstellen. Tatsächlich können Sie einen Symlink überschreiben und so den Pfadnamen aktualisieren, auf den er verweist:
$ 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 : Wie der OP in einem Kommentar darauf hingewiesen, die mit --force
Option macht ln
einen Systemaufruf durchzuführen , unlink()
bevor symlink()
. Unten strace
beweist die Ausgabe auf meiner Linux-Box:
$ 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
Die endgültige Antwort lautet also "nein".
BEARBEITEN : Das Folgende wurde aus der Antwort von Arto Bendiken auf unix.stackexchange.com, circa 2016, kopiert .
Dies kann in der Tat atomar erfolgen rename(2)
, indem zuerst der neue Symlink unter einem temporären Namen erstellt und dann der alte Symlink auf einmal sauber überschrieben wird. Wie in der Manpage angegeben :
Wenn sich newpath auf einen symbolischen Link bezieht, wird der Link überschrieben.
In der Shell würden Sie dies mv -T
wie folgt tun :
$ mkdir a b
$ ln -s a z
$ ln -s b z.new
$ mv -T z.new z
Sie können strace
diesen letzten Befehl ausführen, um sicherzustellen, dass er tatsächlich rename(2)
unter der Haube verwendet wird:
$ 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
Beachten Sie, dass oben beide mv -T
und strace
Linux-spezifisch sind.
Verwenden Sie unter FreeBSD mv -h
abwechselnd.
Anmerkung des Herausgebers: So macht es Capistrano seit Jahren, seit ~ 2.15. Siehe diese Pull-Anfrage .
ln
Befehl (oder die API gleichwertig) ausgeben, der den alten Link überschreibt? Welches Problem hast du?