5

Normally to change a symlink target one will first unlink the file and then re-creating the symlink with the new target path. However it will be assigned a new inode number.

Maybe there is a private Mac api with an update_target_for_symlink() function, so the inode can stay the same?

In case you wonder what I need it for.. a file manager. I doubt that this is possible at all. Anyways thats what makes it interesting.

neoneye
  • 50,398
  • 25
  • 166
  • 151

3 Answers3

8

It looks a lot like this isn't possible at all.

bukzor
  • 37,539
  • 11
  • 77
  • 111
2

A link is an additional name associated with the inode. So there is no possibility to retarget a link since the link is not a unique object targeting a file. It is more a secondary name of a file.

Thats why you have to unlink it first (delete the name associated with the file) and then create a new link (add a additional name) to the new file.

The Inode of the link does not belong to the link, it belongs to the file. A file consists of list of names("links"), an identifier (inode) and a bunch of data blocks containing the file contents.

A symlink should be possible to rename, cause it only refers to the text name of a file.

From manual: There are nine system calls that do not follow links, and which operate on the symbolic link itself. They are: lchflags(2), lchmod(2), lchown(2), lstat(2), lutimes(2), readlink(2), rename(2), rmdir(2), and unlink(2).

UnixShadow
  • 1,222
  • 8
  • 12
  • 2
    The first part is true for hardlinks, but is more or less irrelevant as the OP is asking about symlink. – BCS Aug 23 '10 at 04:28
2

Upon looking closer, ln -sf seems to do what you want.

The first column is the inode number. Note it doesn't change:

$ ln -s foo bar
$ ls -li bar
    16503 lrwxrwxrwx 1 golemon golemon 3 2010-08-21 12:29 bar -> foo
$ ln -sf buz bar
$ ls -li bar
    16503 lrwxrwxrwx 1 golemon golemon 3 2010-08-21 12:29 bar -> buz

It looks like ln-sf uses simply unlink() and symlink() to accomplish this:

$ strace ln -sf quux bar
    <snip>
    symlink("quux", "bar")                  = -1 EEXIST (File exists)
    unlink("bar")                           = 0
    symlink("quux", "bar")                  = 0

$ ls -li bar
    16503 lrwxrwxrwx 1 golemon golemon 4 2010-08-21 12:31 bar -> quux
bukzor
  • 37,539
  • 11
  • 77
  • 111
  • 1
    I feel like I'm missing something because @neoneye sounds like he already tried this, and it seems to completely contradict what @UnixShadow said. – bukzor Aug 21 '10 at 19:38
  • 1
    I see you get the same inode. This is really interesting. However I get different inodes when I try the same. I guess you are not on Mac. What platform are you on? – neoneye Aug 22 '10 at 03:11
  • If foo was a directory, you would need `ln -snf buz bar`. – vilpan Dec 21 '14 at 15:52