symbolic link without expanding $HOME or "~"?

4.1k Views Asked by At

the basic idea is that I want to link to path that's relative to $HOME, rather than explicitly expand the $HOME variable, as I want to make sure the link works on multiple machines, e.g.,

when I do

ln -s ~/data datalnk

I want it to be directed to directory /home/user/data on one machine which has a user $HOME of /home/user, and to /home/machine/user/data on another machine which has a user $HOME of /home/machine/user/data.

I cannot create a symbolic link on the second machine using

ln -s /home/machine/user /home/user

because I don't have the permission to do that, and I cannot link relative paths as the two machines have different hierarchies of directories.

anyideas on possible ways to fix or circumvent this?

EDIT:

what I am really trying to accompanish is to make the same link work on two macihnes, where the targets have the same directories in terms of their relative path to $/HOME only, not their absolute path, and not their relative path to the link either.

3

There are 3 best solutions below

8
On BEST ANSWER

The only way to make symlinks dynamic in this way is to use a relative path instead of an absolute path. In other words, don't start your path with /.

For example:

cd
ln -s data datalnk

At runtime your app or script will need to refer to ~/datalnk or $HOME/datalnk.

You haven't really said what you're trying to accomplish, so I can't really tell whether I'm solving your problem or suggesting that you need to go at it a different way.

0
On

First of all: It can't be done directly. Symbolic links are plain text files, no extensions are performed. If you can't formulate a fixed relative or absolute path to the place you are referring, you can't symbolically link to it.

You can build a script to put links to appropriate directories in appropriate places, but the best way depends on your application.

1
On

tl,dr it won't work

You can use an escaping mechanism such as single-quotes to get the ~ into the symbolic link:

> cd ~
> echo hello > a    
> ln -s '~/a' b

However, ~ is a shell expansion and is not understood by the filesystem (actually, to the filesystem it's "just another character"). This is a good thing -- want the file-system layer to know about environment variables, as ~ is generally determined by $HOME?

> ls -l b
lrwxrwxrwx    1 root     root             3 Oct 27 17:39 b -> ~/a
> ls b
ls: b: No such file or directory 

You could still "manually" look at said symbolic link entries (as done with ls -l), but that would have to be done in a non-transparent fashion by a program (think of a ".LNK" in Windows). As can be seen, the filesystem just doesn't understand ~.

Happy sh'ing.