2

I've been using Linux on and off for the last 15 years and today I came across something in bash that surprised me.

Setup the following directory structure:

$ cd /tmp
$ mkdir /tmp/symlinktest
$ mkdir /tmp/symlinktest/dir
$ mkdir /tmp/symlinktarget

Now create two sym links in symlinktest pointing to symlinktarget:

$ cd /tmp/symlinktest
$ ln -s ../symlinktarget Asym
$ ln -s ../symlinktarget Bsym

Now, in bash, the following tab completion does strange things. Type the following:

$ cd dir
$ cd ../A[TAB]

Pressing the tab key above completes the line to:

$ cd ../Asym/

as I expected. Now press enter to change into Asym and type:

$ cd ../B[TAB]

This time pressing the tab key completes the link to:

$ cd ../Bsym[space]

Note that there is now a space after the Bsym and there is no trailing slash.

My question is, why when changing from the physical directory "dir" to Asym it recognises that Asym is a link to a directory, but when changing from one sym link to another, it doesn't recognise that it's a link to a directory?

In addition, if I try to create a new file within Asym, I get an error message:

$ cd /tmp/symlinktest/Asym
$ cat hello > ../Bsym/file.txt
-bash: ../Bsym/file.txt: No such file or directory

I always thought that symlinks were mostly transparent except to programs that need to manipulate them. Is this normal behaviour?

Many thanks,

Andy

1
  • 1
    shell scripting is still programming; the question doesn't come anywhere near this description from the "vote to close" dialog: "This question is related to computer hardware or computer software in general"
    – just somebody
    Commented Jun 11, 2010 at 13:05

1 Answer 1

2

bash's cd builtin does a bit of magic with ...

When you do:

cd ../Bsym

It looks at $PWD, removes the last component, adds the Bsym component. This is what cd and cd -L do, as opposed to cd -P. Also see pwd -L and pwd -P.

When you do:

cat hello > ../Bsym/file.txt

This magic doesn't take place. $PWD isn't used, /proc/self/cwd is used instead. The cwd is an inode, and .. is just the parent inode, which happens to be /tmp.

1
  • Thanks, that makes sense now, there's always more you can learn! I'll have to be more careful now using .. within symbolically linked directories. I always assumed that they worked just like normal directories, but obviously not. I had kind of suspected it was something about .. not knowing if it should be the parent of the link or the parent of the linked directory but you've made it clear. Many thanks for the quick reply. Commented Jun 11, 2010 at 16:11

You must log in to answer this question.

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