PowerShell / PowerShell

PowerShell for every system!
https://microsoft.com/PowerShell
MIT License
43.55k stars 7.06k forks source link

`-LiteralPath` still interprets `~` #21555

Closed Hashbrown777 closed 4 days ago

Hashbrown777 commented 2 weeks ago

Prerequisites

Steps to reproduce

I [personally] think LiteralPath should not be interpreting any special characters. However, if understandably this cannot be helped at this stage, tilde should be mentioned in the documentation. './~' can be used to rectify this if possible within your script, but it erodes trust in what else PowerShell is doing. The example uses cd, but this affects everything (Get-Item, Remove-Item, et cetera).

Expected behavior

PS> $PWD.Path
/home/hashbrown
PS> New-Item -Type Directory -Name '~' >$NULL
PS> cd -LiteralPath '~'
PS> $PWD.Path
/home/hashbrown/~

Actual behavior

PS> $PWD.Path
/home/hashbrown
PS> New-Item -Type Directory -Name '~' >$NULL
PS> cd -LiteralPath '~'
PS> $PWD.Path
/home/hashbrown

Error details

-LiteralPath
Specifies the path to be resolved.
The value of the LiteralPath parameter is used exactly as typed.
No characters are interpreted as wildcard characters.
If the path includes escape characters, enclose it in single quotation marks (').
Single quotation marks tell PowerShell not to interpret any characters as escape sequences.

(from https://learn.microsoft.com/en-us/powershell/module/*/*?view=powershell-7.4#-literalpath)

Environment data

Name                           Value
----                           -----
PSVersion                      7.4.2
PSEdition                      Core
GitCommitId                    7.4.2
OS                             Fedora Remix for WSL
Platform                       Unix
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0…}
PSRemotingProtocolVersion      2.3
SerializationVersion           1.1.0.1
WSManStackVersion              3.0

Visuals

No response

mklement0 commented 2 weeks ago

I agree that the docs should be amended to clarify that the literal aspect of the -LiteralPath parameter only relates to not treating its arguments as a wildcard pattern, not also to not interpreting an argument-initial ~ (either standalone or if followed by \ or //) as the home location of the provider underlying the current location (which is interpreted as such irrespective of whether you use -LiteralPath or -Path).

(I don't think that changing the current behavior to also treat ~ literally would be considered acceptable, as it is may break existing scripts.)

Note that, unlike in POSIX-compatible shells:

Hashbrown777 commented 2 weeks ago

@mklement0 that's interesting that it's not powershell doing it.. but the same systems using the other 'native' CLI do not have this issue (id est it is the shell expanding ~) image If the [.net] provider cannot be amended, and the cmdlets wont be changed to escape ~ before handing over to it (to bring it in line with other shells..), it absolutely must be in all documentation (as it functions counter to non-pwsh expectations)

rhubarb-geek-nz commented 2 weeks ago

@mklement0 that's interesting that it's not powershell doing it

I think it is PowerShell doing it because there is nobody else doing it, the operating system does not do it. What I think @mklement0 is saying is it is not the command line variable expansion doing it, it is the PowerShell file system provider almost treating ~ as a logical drive.

Hashbrown777 commented 2 weeks ago

I took it to mean it's .NET doing it, as pwsh would be using it to provide filesystem access, and the other CLI not utilising .NET is why 'nobody else is doing it'. But I could be wrong, I'd have to write some C# or something to check.

If you're right then this definitely falls closer to 'we should change this, not just document it' :/

rhubarb-geek-nz commented 2 weeks ago

I'd have to write some C# or something to check.

PSCmdlet.GetUnresolvedProviderPathFromPSPath does this translation, in my test case from "~/.ssh/known_hosts" to "C:\Users\rhubarb\.ssh\known_hosts".

Typically you use GetResolvedProviderPathFromPSPath for -Path and GetUnresolvedProviderPathFromPSPath for -LiteralPath.

So not the command line expansion. not the .NET runtime, it is the PowerShell file system provider.

This translation does other important things like give you the current location per thread, as current directory is a process wide thing.

StevenBucher98 commented 1 week ago

I suggest making a doc issue to clarify the use of -LiteralPath ,https://github.com/MicrosoftDocs/PowerShell-Docs. (cc @sdwheeler). I will leave it up to working group to decide how to approach this, feels like a pretty niche case but definitely sympathize with the confusing messaging with "literal path"

GitHub
GitHub - MicrosoftDocs/PowerShell-Docs: The official PowerShell documentation sources
The official PowerShell documentation sources. Contribute to MicrosoftDocs/PowerShell-Docs development by creating an account on GitHub.
sdwheeler commented 1 week ago

I'm not sure that this is unique to -LiteralPath. The workaround for the OP is to qualify the path.

/home/sdwheeler> $pwd

Path
----
/home/sdwheeler

/home/sdwheeler> New-Item -Type Directory -name ~

    Directory: /home/sdwheeler

UnixMode         User Group         LastWriteTime         Size Name
--------         ---- -----         -------------         ---- ----
drwxr-xr-x  sdwheeler sdwheeler  05/06/2024 13:37         4096 ~

/home/sdwheeler> cd ~
/home/sdwheeler> cd ./~

Path
----
/home/sdwheeler/~
mklement0 commented 1 week ago

Yes, the interpretation of a stand-alone ~ as a path or a ~/-prefixed path as ~ referring to the provider's home location is unrelated to the -LiteralPath / -Path distinction, but the point is that it's reasonable to assume that if you use -LiteralPath that ~ too will be treated literally, so adding a note to the docs would be helpful.

sdwheeler commented 5 days ago

The docs have been updated.

SteveL-MSFT commented 5 days ago

Resolving as the current code behavior would be a breaking change and I do think some folks would be surprised if ~ didn't go home even for -literalpath.

microsoft-github-policy-service[bot] commented 4 days ago

This issue has been marked as answered and has not had any activity for 1 day. It has been closed for housekeeping purposes.

microsoft-github-policy-service[bot] commented 4 days ago

📣 Hey @Hashbrown777, how did we do? We would love to hear your feedback with the link below! 🗣️

🔗 https://aka.ms/PSRepoFeedback

Microsoft Forms