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.
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