how to change symlink target while preserving inode
Asked Answered
K

3

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.

Kendricks answered 28/7, 2010 at 0:48 Comment(0)
A
8

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

Adriell answered 16/8, 2010 at 23:19 Comment(1)
yeah, that is exactly the problem :-)Kendricks
R
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).

Rodl answered 20/8, 2010 at 13:32 Comment(1)
The first part is true for hardlinks, but is more or less irrelevant as the OP is asking about symlink.Nonna
A
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
Adriell answered 21/8, 2010 at 19:33 Comment(3)
I feel like I'm missing something because @Kendricks sounds like he already tried this, and it seems to completely contradict what @Rodl said.Adriell
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?Kendricks
If foo was a directory, you would need ln -snf buz bar.Pinkster

© 2022 - 2024 — McMap. All rights reserved.