2

I want to create a symbolic link to a file in my current working directory.

Say that I have a top level tree that looks like this:

.
├── dir1
│   └── hello.so
└── dir2

2 directories, 1 file

I change my working directory to dir1. Now, I want to create my symbolic link of hello.so in dir2.

I try ln -s ./hello.so ../dir2/. However, this does not work, as it creates a link to ./hello.so, rather than expanding the ./ as I would expect.

ln -s ${PWD}/hello.so ../dir2/ works fine, but it's a bit verbose.

I fear I may have misunderstood what ./ expansion is, but I haven't been able to figure out what I've got wrong.

In case it's a problem specific to my environment, I am on Bash 5.0.2. I haven't been able to find any fancy flags in the ln man.

1
  • aye, an unfortunate double typo, thanks for noticing. I can confirm that I was looking at ln. Fixed with an edit Commented Feb 6, 2019 at 11:37

2 Answers 2

3

./ is not an expansion, it's a literal relative path: find the entry called . in the current directory, treat it as a directory (/), and then carry on from there to find hello.so inside it.

Every directory has a . entry that points to itself. Every directory also has a .. entry that points to its parent (except the root directory). These are not particularly special: they are ordinary directory entries, just like your regular files and directories, only they were created automatically.

Symbolic links store a literal string value inside them, and ln -s stores exactly the value you give it without any processing. That is the result you saw: ./hello.so was placed into the link exactly as you instructed.


If you want a complete path to be in the link, you need to provide a complete path, whether with $PWD or $(pwd) or just writing it out.

The paths are interpreted relative to the location, however, so this would be a valid link to that file:

ln -s ../dir1/hello.so dir2/hello.so

or any other path to the place you want the link to be - ../dir1/hello.so will be stored in the link in the same way regardless.

In this case, when the link is accessed ../dir1/hello.so will be looked for relative to where the link is, and it will find your file. This is robust if the whole directory tree is moved, while an absolute path wouldn't be. Depending on what you want to achieve, either of those might be the right option for you.

2

From dir1:

ln -s ../dir1/hello.so ../dir2

From dir2:

ln -s ../dir1/hello.so .

(the final dot is optional here)

From the top directory:

ln -s ../dir1/hello.so dir2

The first argument is "contents of" the symbolic link itself (what's called the source in the manual). In this case it points to the file using a relative path from its location. The second argument is where the symbolic link should be placed.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .