Skip to content

windows: '~' Home reference bug  #20761

Open

Description

Prerequisites

Steps to reproduce

when i update PowerShell in my windows 11 workstation version to 7.4.0 below is version
$ $PSVersionTable

Name Value


PSVersion 7.4.0
PSEdition Core
GitCommitId 7.4.0
OS Microsoft Windows 10.0.22621
Platform Win32NT
PSCompatibleVersions {1.0, 2.0, 3.0, 4.0…}
PSRemotingProtocolVersion 2.3
SerializationVersion 1.1.0.1
WSManStackVersion 3.0

when i use the ~ to refer my work home, that may conjunct with current path; at old version that method like resolve ~ to $HOME environment variation.
Hope can resolve this problem. thanks

Expected behavior

ps> more ~\test
1

Actual behavior

# xxxxxx @ SHC5CG33131WZL in ~\AppData\Local\Temp\tmphcnstt.tmp [18:41:39]
$ more ~\test
Cannot access file C:\Users\xxxxxx\AppData\Local\Temp\tmphcnstt.tmp\~\test

Error details

No response

Environment data

Name                           Value
----                           -----
PSVersion                      7.4.0
PSEdition                      Core
GitCommitId                    7.4.0
OS                             Microsoft Windows 10.0.22621
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

Activity

  1. yuanjs-0108 commented on Nov 23, 2023

    @yuanjs-0108
    Author

    it actually use more.com in powershell, and it still not work in such like
    code.exe(vscode) --diff
    This kinds of external command that need path as parameters.
    So have u fix it or add this feature?
    Or I need to take an issue to vscode to remain them to fix this problem ? 😃

  2. 237dmitry commented on Nov 23, 2023

    @237dmitry

    it actually use more.com in powershell

    If you about powershell.exe you are confusing a function with an application

    Get-Command more*
    
    CommandType     Name                                               Version    Source
    -----------     ----                                               -------    ------
    Function        more
    Application     more.com                                           10.0.22... C:\WINDOWS\system32\more.com
  3. mklement0 commented on Nov 23, 2023

    @mklement0
    Contributor

    To summarize:

    • On Windows, ~ is only recognized by the provider cmdlets, such as Get-Content and Get-ChildItem (there it refers to the home location of the provider underlying the current location; for the FileSystem provider, that is $HOME, i.e. the current user's home directory (same as $env:USERPROFILE on Windows).

    • External programs - such as more.com or code - do not understand ~ and - unlike on Unix-like platforms - on Windows PowerShell performs no translation of ~ to the value of $HOME behind the scenes.

    • In Windows Powershell more ~\test happened to work, because there more refers to a PowerShell function by that name (run $function:more to see its body) that wraps more.com and passes the file-path argument to Get-Content, which, as stated, does understand ~.

    • Because this function was removed in PowerShell Core, more ~\test now passes ~\test directly to more.com, which therefore fails (because more.com doesn't understand ~).

  4. 237dmitry commented on Nov 23, 2023

    @237dmitry

    Nice summary of several recent topics.

  5. tats-u commented on Dec 6, 2023

    @tats-u

    In Bash in WSL:

    tatsu@TATSU-NB-4TH:~$ sh -c 'echo "$0" "$@"' ~ ~root ~/ ~/notfound foo~bar
    /home/tatsu /root /home/tatsu/ /home/tatsu/notfound foo~bar
    

    Bash expands ~ at the beginning as an appropriate home directory, but PowerShell will not at all.
    This specification of PowerShell must be changed.

    tatsu@TATSU-NB-4TH:~$ sh -c 'echo "$0" "$@"' "~" '~' ~
    ~ ~ /home/tatsu
    

    ~ is not converted if quoted.

  6. tats-u commented on Dec 6, 2023

    @tats-u

    The behaviours are the same on Linux

    This means pwsh for Windows has intentionally disabled this feature.

    $env:USERPROFILE is tooooooooooo loooooooooong to be typed frequently.

  7. tats-u commented on Dec 6, 2023

    @tats-u

    Now tilde does have two existing historical interpretations in Windows, one as a common prefix or extension for temporary files,

    Unlike Unix, we do not have to expand ~user because we do not have to care about user profile folders of other users in Windows.

    Also Bash does not expand ~notexistinguser.

    $ /bin/echo ~root ~johndoe ~root/foobar ~johndoe/bazqux
    /root ~johndoe /root/foobar ~johndoe/bazqux
    

    the second in batch files when getting the directory where the batch file comes from, eg %~dp0.

    It is not affected because it does not start with ~.

  8. tats-u commented on Dec 6, 2023

    @tats-u

    I forgot Windows Server. ~user is necessary even in Windows. However, it will be difficult to take users whose names contain space into account.

  9. tats-u commented on Dec 6, 2023

    @tats-u

    ~user is not expanded in cmdlets and the tab completion 7.3 or prior in Windows. Current user profile ~ has much higher priority than other users' ones.

  10. mklement0 commented on Dec 6, 2023

    @mklement0
    Contributor

    Implementing ~<username> expansion is the subject of this long-standing feature request:

    As for usernames with spaces (which are rare, as is ~<username> use in general, but there's no reason not to fully emulate the tilde expansion of POSIX-compatible shells): The spaces need to be `-escaped, e.g., ~jane` doe

    As for bringing the emulation of tilde expansion to Windows (for native programs only, as on Unix): In addition to the discussion in the previously linked issue, there is a also a PR, though it would initially be just an experimental feature:

  11. mklement0 commented on Dec 6, 2023

    @mklement0
    Contributor

    I agree that ~<username> isn't terribly useful, rhubarb-geek-nz, and personally I don't miss it.
    But, as stated, there's no reason not to fully emulate the tilde expansion features of POSIX-compatible shells.

    Good point re the different behaviors in different shells - I was only aware of the Bash behavior, where only a verbatim username works: This is in line with the POSIX spec (you can infer it from the fact that tilde expansion is prescribed to occur before parameter expansion).

    This, and the prevalence of Bash, point to the fact that ~<username> is primarily an interactive convenience, such as typing ls ~j<tab>, which expand to ls ~jdoe and therefore refers to user jdoe's home directory.

    Thus, one option is to limit PowerShell to emulating the POSIX-compliant / Bash behavior and allow verbatim usernames only.

    To also support variable-based usernames, the logic would have to be (as implied by the usual quoting rules of POSIX-compatible shells), with $user = 'jdoe':

    • ~jdoe, ~$user, ~"$user" should expand to jdoe's home dir. (but only - as usual - if either followed by no additional characters or an unquoted /)
    • Any other forms shouldn't (e.g., '~jdoe', "~$user")

    This would make it a bit more useful, because it makes it suitable for use in scripts too, as you note.

    I suggest continuing this discussion in #12387, if necessary.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Needs-TriageThe issue is new and needs to be triaged by a work group.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions