Search code examples
linuxunixfilesystemssymlinkcd

Path ambiguity through symbolic links


I have noticed a strange behavior in UNIX systems:

I'm standing in /noob/
I have a symbolic link to a folder (A@ -> /B/C/D/A)
I enter the folder via my symlink (cd A) 
pwd says /noob/A/
In /B/C/D/A/ i have a file abc which I can see now.
I want to copy it to /noob/
I type cp abc ..
I type cd ..
I end up in /noob/ which is empty - but the file ended up in /B/C/D/ ???

How come this ambiguity as to where cp and cd points when given .. as argument? I find it confusing. Can anyone explain it in terms I'll understand? (=simple)

All the best, and please forgive a UNIX-noob a stupid question. Lasse


Solution

  • First let's have a look at how cd command does behave by looking at the help menu. What we are looking for is option -L (the default behavior) and option -P

    $ help cd cd: cd [-L|[-P [-e]] [-@]] [dir]
    Change the shell working directory.
    
    ...
    ...
    
    Options:
        -L      force symbolic links to be followed: resolve symbolic links in
        DIR after processing instances of `..'
        -P      use the physical directory structure without following symbolic
        links: resolve symbolic links in DIR before processing instances
        of `..'
    ...
    ...
    

    Important section

    The default is to follow symbolic links, as if `-L' were specified.
    `..' is processed by removing the immediately previous pathname component
    back to a slash or the beginning of DIR.
    
    Exit Status:
    ...
    

    As you can see the default behavior of cd is not what you think it is since he will manipulate the $PWD variable accessed by pwd command in his own way, at each step you can run pwd command or do an echo $PWD to see how it reacts with the different cd commands hereunder.

    Let's play with cd command:

    We start from the following folder, with a sym link:

    [/home/arobert/test/noob] >
    ls -ltra
    total 8
    drwxrwxr-x 5 arobert arobert 4096  5月 11 09:48 ..
    lrwxrwxrwx 1 arobert arobert   26  5月 11 09:48 A -> /home/arobert/link/B/C/D/A
    drwxrwxr-x 2 arobert arobert 4096  5月 11 10:03 .
    

    USAGE EXAMPLES:

    [/home/arobert/test/noob] >
    cd A
    [/home/arobert/test/noob/A] >
    cd ..
    [/home/arobert/test/noob] >
    cd -L A
    [/home/arobert/test/noob/A] >
    cd ..
    [/home/arobert/test/noob] >
    cd -P A
    [/home/arobert/link/B/C/D/A] >
    cd -P ..
    [/home/arobert/link/B/C/D] >
    cd /home/arobert/test/noob/
    [/home/arobert/test/noob] >
    cd A
    [/home/arobert/test/noob/A] >
    cd -P ..
    [/home/arobert/link/B/C/D] >
    

    Now let's play with readlink and cp command:

    Let's say we have entered the symlink that points to A -> /home/arobert/link/B/C/D/A in which we have a file a

    [/home/arobert/test/noob/A] >
    ls -ltra
    total 8
    drwxrwxr-x 3 arobert arobert 4096  5月 11 09:55 ..
    -rw-rw-r-- 1 arobert arobert    0  5月 11 10:10 a
    drwxrwxr-x 2 arobert arobert 4096  5月 11 10:10 .
    

    from this folder let's look at where does point . and .. by using readlink -f command:

    [/home/arobert/test/noob/A] >
    readlink -f .
    /home/arobert/link/B/C/D/A
    
    [/home/arobert/test/noob/A] >
    readlink -f ..
    /home/arobert/link/B/C/D
    

    By consequence, when you run from the location /home/arobert/test/noob/A equivalent to /home/arobert/link/B/C/D/A the command cp a .. the file will be moved to /home/arobert/link/B/C/D as .. points to it.

    What you can do now:

    • Use absolute path with your cp command to avoid bad surprise.
    • Call the command from /home/arobert/test/noob/ directory using

    For example:

    [/home/arobert/test/noob] >
    cp A/a .
    

    as readlink -f . points to the correct folder

    [/home/arobert/test/noob] >
    readlink -f .
    /home/arobert/test/noob
    

    Result:

    [/home/arobert/test/noob] >
    ls -ltra
    total 8
    drwxrwxr-x 5 arobert arobert 4096  5月 11 09:48 ..
    lrwxrwxrwx 1 arobert arobert   26  5月 11 09:48 A -> /home/arobert/link/B/C/D/A
    -rw-rw-r-- 1 arobert arobert    0  5月 11 10:13 a
    drwxrwxr-x 2 arobert arobert 4096  5月 11 10:13 .