Moving the target of a symbolic link

Hello all,

On a Solaris box, I am trying to move the target of a symbolic link.

Let's say the symbolic link looks like the following:
/dir1/dir2/link -> /some/dir/target

I would like to know of a simple way to move the target of the symbolic link and not the link itself. I'd like to move /some/dir/target to /some/dir/target_v01 using the symbolic link as an argument to a command, if possible.

Using the mv command like below results in renaming the symbolic link and this is not the desired behavior in my case:

mv /dir1/dir2/link /dir1/dir2/target_v01

...will result in the rename of the symbolic link:

/dir1/dir2/target_v01 -> /some/dir/target

Thank you!

Create a redirect - a second link. Rename the original physical file, or create the second file - then create a symlink named as the original file name pointed at the new file name.

Don't get carried away - there is a limit to the number of links in a path.
The error code ELOOP:

ELOOP Too many symbolic links were encountered in resolving pathname, or O_NOFOLLOW was specified but pathname was a symbolic link

.

And having lots of links for a file is a maintenance mess - ie., backups etc.

This is a great discussion about links:

symlink(7) - Linux manual page

If you want to rename the target of a symbolic link, you need to actually rename that target.

Use "readlink" for that.

For Solaris, have a readlink function like this:

readlink() {
  [ -h "$1" ] &&
  ls -ld "$1" | sed -n 's/.* -> //p'
}

if target=`readlink /dir1/dir2/link` && [ -f "$target" ]
then
   echo mv "$target" "$target"_v01
fi

Remove echo to really run it.
But what should happen with the dangling symlink?

Only if you don't have readlink, which I know Solaris 11 does.

And even then, this is works better:

#include <unistd.h>
#include <stdio.h>
int main( int argc, char **argv )
{
    char buffer[ 32 * 1024 ];
    ssize_t result = readlink( argv[ 1 ], buffer, sizeof( buffer ) );
    if ( result > 0 )
    {
        printf( "%s\n", buffer );
        return( 0 );
    }
    return( -1 );
}

Just run

cc readlink.c -o readlink

You can add some error checking if you'd like.