Take the 2-minute tour ×
Super User is a question and answer site for computer enthusiasts and power users. It's 100% free, no registration required.

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

share|improve this question

migrated from stackoverflow.com Jun 11 '10 at 14:02

This question came from our site for professional and enthusiast programmers.

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 Jun 11 '10 at 13:05

1 Answer 1

up vote 2 down vote accepted

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.

share|improve this answer
    
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. –  Andy Castles Jun 11 '10 at 16:11

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.