Repository navigation
Description
Note:
- This issue is meant to supersede Some cmdlets don't respect
-LiteralPathwhen it comes to backslashes #8158 and Should we do path normalizations on Unix well as on Windows? #6833 and "Rogue" filenames that contain a backslash break automatic globbing for native commands on macOS and Linux #10682 .
From the committee decision at #8587 (comment):
Filesystem accepting both
/and\on all systems is an explicit cross platform experience decision for PowerShell.
Given that it's currently impossible on Unix-like platforms - where \ is a legal filename character - to access or wildcard-match filenames with embedded \ chars., the following fixes are needed:
-
Wildcard matching must able to match
\chars., namely via?or*or[\].- Note that inside
[...],\shouldn't require escaping, analogous to[.]matching a literal.in a regex.
- Note that inside
-
-Pathand-LiteralPatharguments must support`-escaping of\chars. to request their literal treatment. -
The
.PS*provider property values (.PSPath,.PSParentPath,.PSChildName) must reflect the escaped path. -
To-native-path conversions such as with
Convert-Pathmust remove the escaping. -
Native globbing must not break if a wildcard pattern happens to match a filename that contains
\.
Note:
-
Even the above doesn't address the awkwardness of the - unescaped -
.FullNamevalue ofSystem.IO.FileSystemInfonot being directly usable with the filesystem provider; e.g., with the provider bug fixed, something like(Get-ChildItem "$HOME/a\b").FullNamewould return something like/Users/jdoe/a\b- unescaped. -
Similarly, native paths from outside sources with embedded
\- e.g., read from a file - will break in PowerShell commands, unless explicit escaping with-replace '`', '\`'is performed. -
`as the escape char. means that it requires doubling inside"..."and therefore also in unquoted arguments in order to be passed through; i.e., the following calls would be equivalent and match a file literally nameda\b:
Get-Item 'a`\b'
Get-Item "a``\b" # !!
Get-Item a``\b # !! implicitly treated like a "..." string-
Handling
`instances that precede a char. other than\gets quite tricky:-
Literal paths: So as not to break the existing ability to match
`literally in paths,`must be special only before\and before`itself. This follows the model of\use in double-quoted strings in Bash, but introduces the awkwardness of needing to interpret'a`b'and'ab' `` the same (similar to how"a\b"and `"a\b"` are equal in Bash). -
Wildcard paths: Wildcard matching itself always requires doubling of
`for literal use; e.g.,
'a`b' -like 'a`b'is$false, and only'a`b' -like 'a``b'is$true(edge case:'a`' -like 'a`'is also$true- the trailing syntactically incomplete use of`is interpreted as a literal).- However, use of wildcards with the filesystem provider:
- currently makes
Get-Item -Path 'a`b'match a file literally nameda`b, even though it shouldn't. - currently doesn't find a match with
Get-Item -Path 'ab'and neither withGet-Item -Path 'a?', even though it should.
- currently makes
- In other words: wildcard handling by the filesystem provider is currently broken - this may be related to Backtick escaping inconsistent #7999.
- While falling back to literal interpretation is perhaps useful, especially given that
-Pathis the default parameter, this should be fixed, separately.
- However, use of wildcards with the filesystem provider:
-
Steps to reproduce
On macOS or Linux, run the following Pester tests:
# Note: -Skip isn't yet supported at the level of Describe and Context blocks.
# See https://github.com/pester/Pester/issues/442
if ($env:OS -eq 'Windows_NT') {
Write-Warning "Tests apply to Unix-like platforms only" }
else {
Describe "Support for backslashes in Unix filenames" {
BeforeAll {
Push-Location TestDrive:\
# File with literal backslash in its name.
touch 'a\b'
$nativePath = ($PWD.ProviderPath -replace '/$') + '/' + 'a\b'
$escapedName = 'a`\b'
$escapedPath = ((Get-Item .).PSPath -replace '/$') + '/' + $escapedName
# File with literal backtick in its name.
touch 'a`b'
}
It "Backslashes can be matched with wildcards" {
(Get-Item -Path 'a?b').Name | Should -BeExactly 'a\b'
(Get-Item -Path 'a*b').Name | Should -BeExactly 'a\b'
(Get-Item -Path 'a[\]b').Name | Should -BeExactly 'a\b'
}
It "Backtick-escaped backslashes match literal ones in filenames" {
(Get-Item -Path 'a`\b').Name | Should -BeExactly 'a\b'
(Get-Item -LiteralPath 'a`\b').Name | Should -BeExactly 'a\b'
}
It "Backticks not preceding a backslash or backtick are literals in literal paths" {
(Get-Item -LiteralPath 'a`b').Name | Should -BeExactly 'a`b'
}
It "Doubled backticks are also literals in literal paths" {
(Get-Item -LiteralPath 'a``b').Name | Should -BeExactly 'a`b'
}
It "Backtick-escaped backticks must be recognized as a literal backtick in wildcard paths" {
(Get-Item -Path 'a``?').Name | Should -BeExactly 'a`b'
}
It "Provider properties contain escaped paths" {
(Get-Item -LiteralPath 'a`\b').PSChildName | Should -BeExactly $escapedName
(Get-Item -LiteralPath 'a`\b').PSPath | Should -BeExactly $escapedPath
}
It "Convert-Path removes the PS-specific escaping" {
Get-Item -LiteralPath 'a`\b' | Convert-Path | Should -BeExactly $nativePath
}
It "Native globbing doesn't break when a filename with a backslash is among the matches" {
/bin/echo a* | Should -Not -Match '\*'
}
AfterAll {
Pop-Location
}
}
}Expected behavior
All tests should pass.
Actual behavior
All tests except "Backticks not preceding a backslash or backtick are literals in literal paths" fail.
Environment data
PowerShell Core 6.2.0-rc.1
Activity
SteveL-MSFT commentedon Mar 29, 2019
If we ever get around to #5785, we can decide what the default behavior should be with regards to slashes.
[-]Bug fixes needed to support interchangeable use of "/" and "\" in file paths on Unix-like platforms[/-][+]Bug fixes needed to support interchangeable use of "/" (forward slash) and "\" (backslash) in file paths on Unix-like platforms[/+]mklement0 commentedon Mar 29, 2019
Steve Lee (@SteveL-MSFT), can you please clarify?
Did you mean backslashes?
Does this mean that, for the time being, explicit cross platform experience translates to:
\and/interchangeably on all platforms, as long as you don't expect filenames with embedded\chars. to work on Unix-like platforms"?Do you feel that there are aspects of #8158 and #6833 not covered here?
SteveL-MSFT commentedon Mar 29, 2019
I'm using 'slashes' as a generic term for both forward and backslashes.
Yes, current expectation is that you can use
\and/interchangeably on all platforms, except where filename/directoryname contains\.#6833 (comment) summarizes the PS-Committee stance.
Unlike the square brackets, it's unclear to me how often people use the backtick
`or the backslash\within file/directory names.I'm ok closing the older issues as dupes of this one (although it's a bit backwards...) as I believe this does summarize the issues.
mklement0 commentedon Mar 29, 2019
Thanks, Steve Lee (@SteveL-MSFT).
Good point that use of
`and\in filenames may be rare, but it's still problematic to make native capabilities inaccessible (currently) and providing a workaround is both a nontrivial implementation effort and a pitfall for and burden on those who do wish to use\.I don't think that's problematic, as long as the later issue properly references and summarizes the earlier one(s), and the benefit is that future readers are spared the need to cull information from lengthy exchanges and potential confusion over what the way forward is.
microsoft-github-policy-service commentedon Nov 16, 2023
This issue has not had any activity in 6 months, if this is a bug please try to reproduce on the latest version of PowerShell and reopen a new issue and reference this issue if this is still a blocker for you.
microsoft-github-policy-service commentedon Nov 16, 2023
This issue has not had any activity in 6 months, if this is a bug please try to reproduce on the latest version of PowerShell and reopen a new issue and reference this issue if this is still a blocker for you.
microsoft-github-policy-service commentedon Nov 16, 2023
This issue has not had any activity in 6 months, if this is a bug please try to reproduce on the latest version of PowerShell and reopen a new issue and reference this issue if this is still a blocker for you.
microsoft-github-policy-service commentedon Nov 23, 2023
This issue has been marked as "No Activity" as there has been no activity for 6 months. It has been closed for housekeeping purposes.