windowspowershellpowershell-7

Windows: Resolves path with .. appended to directory name


This project I'm working on has some Windows Perl code that sets a path to dirname(__FILE__) . "../../../../". This code has been working for a couple years now, but I realized that it should actually be 3 ..s: dirname(__FILE__) . "/../../../" to get the path we need. The path indeed resolves to the correct location though. The way the path is put together in Perl is ..\dir1\dir2../../../../. The dir2.. does not look right, but:

> Test-Path ..\dir1\dir2..
True
> Test-Path ..\dir1\dir2..\
False
> Test-Path ..\dir1\dir2..\..\
True

How is PowerShell resolving the path here? Command Prompt shows the same behavior.


Solution

  • A Windows path segment of .. means "parent directory". As such, anything\.. is equivalent to .. There's no reason to check if anything exists.

    C:\>dir /b nonexistent\..\Windows\explorer.exe
    explorer.exe
    

    Taking it back to scenario in the question,

    dirname(__FILE__) . "../../../../"
    ⇒ a/b/c/d/e/f../../../../
    ⇒ a/b/c/d/e/../../
    ⇒ a/b/c/d/../
    ⇒ a/b/c/
    
    dirname(__FILE__) . "/../../../"
    ⇒ a/b/c/d/e/f/../../../
    ⇒ a/b/c/d/e/../../
    ⇒ a/b/c/d/../
    ⇒ a/b/c/
    

    As an aside, this wouldn't work in unix because it doesn't treat .. specially. It's looked up on disk, where it would normally be a hardlink to the parent directory.

    /$ ls -d nonexistent/../usr
    ls: cannot access 'nonexistent/../usr': No such file or directory
    
    /$ ls -d home/../usr
    home/../usr
    
    /$ realpath home/../usr
    /usr