Repository navigation
Description
Note: This is ultimately a duplicate of #15235
PR #8783 brought the ability to use relative paths as symlink targets on Windows.
However, if the target is a directory and the relative path starts with / is just a name (rather than starting with .\), the resulting symlink doesn't behave like a directory with Get-ChildItem.
Note that on Unix, as of PowerShell Core 7.2.0-preview.4, use of relative target paths is still fundamentally unsupported - see #15233
Steps to reproduce
Run on Windows:
# Switch to a temporary directory.
Push-Location -ea Stop ($tmpDir = (New-Item -Type Directory -Force (Join-Path Temp:/ $PID)).FullName)
# Create a dir. to serve as the target, with a single text file in it.
$null = New-Item -Type Directory target -Force
'hi' > target/t.txt
# Define two links:
# * one that targets 'target' - by name only.
# * one that targets '.\target' - explicit reference to the current dir.
$null = New-Item -Type SymbolicLink link1 -Target target -Force
$null = New-Item -Type SymbolicLink link2 -Target .\target -Force
# Now compare the Get-ChildItem behavior of these two links, which
# *should* be the same.
Get-ChildItem link1
Get-ChildItem link2
Pop-Location; Remove-Item -lp $tmpDir -RecurseExpected behavior
With the exception of the directory path in the grouping header, the commands should produce the same output and show the content of the target dir:
Directory: C:\Users\jdoe\AppData\Local\Temp\8748\link1
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a--- 4/5/2021 3:30 PM 4 t.txt
Directory: C:\Users\jdoe\AppData\Local\Temp\8748\link2
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a--- 4/5/2021 3:30 PM 4 t.txt
Actual behavior
Directory: C:\Users\jdoe\AppData\Local\Temp\8748
Mode LastWriteTime Length Name
---- ------------- ------ ----
la--- 4/5/2021 3:30 PM 0 link1 -> target
Directory: C:\Users\jdoe\AppData\Local\Temp\8748\link2
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a--- 4/5/2021 3:30 PM 4 t.txt
Note how link1 present as if it were a flle, as if you had called Get-Item rather than Get-ChildItem on it.
Interestingly, cmd.exe's dir shows analogous behavior, and additionally fails with dir link1\t.txt, which PowerShell handles correctly.
Environment data
PowerShell Core v7.2.0-preview.4 (.NET 6.0.0-preview.2.21154.6) on Microsoft Windows 10 Pro (64-bit; Version 20H2, OS Build: 19042.867)
Activity
237dmitry commentedon Apr 15, 2021
I did not understand what the problem is.
mklement0 commentedon Apr 15, 2021
237dmitry, if you run the code in the initial post, you'll see the problem.
It doesn't always happen, but I've just realized that this issue will go away if what Matěj Kafka (@MatejKafka) reported in #15235 gets fixed (which is the right thing to do), so I'm closing this.
In short: if there's a mismatch between the process' current directory (as reported by
[Environment]::CurrentDir) and PowerShell's (which is typically the case), the symlink target's type (file vs. directory) may be mis-identified.In the case at hand,
target- but not.\target- is mistakenly looked for in[Environment]::CurrentDirand, if there's no such item there, it is assumed to be a file, so that thelink1symlink is created with the wrong type (it behaves like a file, even though its true target is a directory).