PowerShell: `ls` breaks down when path name contains hyphen enclosed in escaped brackets
Prerequisites
- Write a descriptive title.
- Make sure you are able to repro it on the latest released version
- Search the existing issues.
- Refer to the FAQ.
- Refer to Differences between Windows PowerShell 5.1 and PowerShell.
Steps to reproduce
I have a file .\o\abc [defg-0 hijk -lmn].pdf
. Then I try all commands below to ls
it. The first char y/x represents that the corresponding command works or not, i.e. prints the file or throw out error which is in ‘Error details’ part.
y ls '*`[defg*0 hijk -lmn`].pdf' -Recurse
y ls '*defg-0 hijk -lmn*.pdf' -Recurse
x ls '*`[defg-0 hijk -lmn`].pdf' -Recurse
Expected behavior
All three commands above work fine, i.e. print the file specified.
Actual behavior
Just as the first char y/x in each command line shows. It seems that hyphen is recognized as a special char although brackets are escaped.
Error details
Get-ChildItem: Cannot retrieve the dynamic parameters for the cmdlet. The specified wildcard character pattern is not valid: *\[defg-0 hijk -lmn\].pdf
### Environment data
```powershell
Name Value
---- -----
PSVersion 7.2.6
PSEdition Core
GitCommitId 7.2.6
OS Microsoft Windows 10.0.19043
Platform Win32NT
PSCompatibleVersions {1.0, 2.0, 3.0, 4.0…}
PSRemotingProtocolVersion 2.3
SerializationVersion 1.1.0.1
WSManStackVersion 3.0
### Visuals
_No response_
About this issue
- Original URL
- State: closed
- Created 2 years ago
- Comments: 16 (8 by maintainers)
Amen to that.
If backward compatibility weren’t in the picture, I would eliminate the implicit recursion based on the leaf component of the
-Path
component altogether - it is simply too treacherous and confusing.That is, the only way to search for a name or pattern in all directories of the subtree would then be to use either
-Filter
or-Include
, and both-Path
and-LiteralPath
would consistently only specify the starting point for-Recurse
.Therefore, @iSazonov, backward compatibility also gets in the way of your suggestion, because you can (unfortunately) currently do something like
Get-ChildItem $Home/*.txt -Recurse
too look for*.txt
files in the entire subtree, which would break if$Home/*.txt
were to bind to-Include
.We have
filter
which passes the characters to the Windows API which treats*
and?
but not[ ]
as wildcards (not sure what happens on linux but it may treat them differently)We have
literalpath
which should treat nothing as wildcards even though on windows * and ? are forbidden by the filesystem, on linux that would be how you request a file with those characters.And
path
which treats all 3 as wildcards, unless they are backquoted (the backquote is a requirement of the wildcard class, not PowerShell syntax). However backquoted characters are not always processed correctly.Since
-literalpath
does not work with -recurse ,-filter
will work for this case, but the -path won’t because of the backquote problem.@iSazonov looking at the error, it seems that somewhere in processing the parameters something is not seeing
`[
and`]
as escaped and is trying to process what is inside the[ ... ]
as a wildcard expression@LqkUWp specifying -LiteralPath will prevent this happening.