Skip to content

Native globbing: character-individual backtick escaping of wildcard metacharacters is not respected #18038

Closed

Description

Prerequisites

See also (the inverse problem): #10683

Steps to reproduce

On Unix-like platforms, unquoted arguments that look like globbing (wildcard) patterns are automatically resolved to matching paths when calling external programs.

While single- and double-quoting can be used to suppress this behavior, using character-individual backtick escaping does not:

/bin/echo `*

Expected behavior

*

Actual behavior

(list of file and subdirectory names in the current directory)

Error details

No response

Environment data

PowerShell Core 7.3.0-preview.7 on Unix-like platforms.

Visuals

No response

Activity

  1. 237dmitry commented on Sep 6, 2022

    @237dmitry

    Why do you expect this ( * ) output?

    1_001

  2. mklement0 commented on Sep 6, 2022

    @mklement0
    ContributorAuthor

    237dmitry, why do you think that Bash syntax is in any way relevant here?

  3. mklement0 commented on Sep 6, 2022

    @mklement0
    ContributorAuthor

    In PowerShell terms: if Write-Output `" is the same as Write-Output '"', why isn't `* the same as '*' (as it indeed is with Write-Output)?

    Granted, the escaping in `* isn't strictly escaping for syntactic reasons, but if '*' serves to signal to the native globbing feature that it should not be applied, so should `* - unless there's a good reason for this discrepancy that I'm missing.

  4. 237dmitry commented on Sep 6, 2022

    @237dmitry

    why do you think that Bash syntax is in any way relevant here?

    Because in bash /bin/echo * outputs list of files. You escaped `* and /bin/echo gets the clean *

  5. mklement0 commented on Sep 6, 2022

    @mklement0
    ContributorAuthor

    And to bring it back to Bash syntax by analogy: echo \* - which prints verbatim * - is the analog of /bin/echo `* in PowerShell.

    Because in bash /bin/echo * outputs list of files.

    It does in PowerShell too, in an effort to emulate this behavior of POSIX-compatible shells called globbing (pathname expansion). That is, it is the shell that perform this expansion, before the target program is passed the results of this expansion.

    This emulation is the implied premise of this issue, not its subject.

    You escaped `* and /bin/echo get the clean *

    It doesn't, as shown in the initial post.
    It is not /bin/echo that performs the globbing, if that's your misconception.

  6. 237dmitry commented on Sep 6, 2022

    @237dmitry

    It is not /bin/echo that performs the globbing

    /bin/echo receives parameter that already globbed. Isn't it true?

  7. mklement0 commented on Sep 6, 2022

    @mklement0
    ContributorAuthor

    Yes, if you pass *. By contrast, if you quote the * as '*' or "*", PowerShell does not apply native globbing and /bin/echo receives verbatim * (which it prints as-is). And, by PowerShell's quoting / escaping rules, `* should be equivalent to the quoted forms, but isn't.

  8. 237dmitry commented on Sep 6, 2022

    @237dmitry

    should be equivalent to the quoted forms, but isn't.

    I'm already confused with escaping.

    PS > /bin/echo 1`n2
    1
    2
    
    PS > Start-Process /bin/echo -ArgumentList 1`n2
    1
    2
    
    PS > /bin/echo --% 1`n2
    1`n2
    
    PS > (Get-ExperimentalFeature -Name PSNativeCommandArgumentPassing).Enabled
    True
  9. mklement0 commented on Sep 7, 2022

    @mklement0
    ContributorAuthor

    Generally speaking, unquoted literal arguments are parsed as if they were enclosed in "..."; that is, /bin/echo 1`n2 is the same as /bin/echo "1`n2", meaning that escape sequence `n expands to a literal newline (LF).

    Inside "...", `-escaping characters that do not form an escape sequence isn't necessary, but is tolerated; e.g. /bin/echo "`'" is the same as /bin/echo "'" and prints verbatim '.

    However, in an unquoted argument, characters that wouldn't require escaping if enclosed in "..." do require escaping if they contain argument-mode metacharacters, such as ', ", &, |, ..., so that, for instance, you have to use /bin/echo `| to print | verbatim.

    From that perspective alone, * does not require `-escaping, because * isn't an argument-mode metacharacter: leaving the native globbing feature out of the picture, all of the following output * verbatim: Write-Output *, Write-Output '*', Write-Output "*", and Write-Output `*

    The fact that with respect to native globbing it makes a difference whether you use '...' / "..." quoting (suppression of the feature) or not, already amounts to special-casing the usual syntax rules, and this special-casing is applied by PowerShell itself, during parameter binding (I don't know the details).

    My point is that this special-casing should also apply to `* and `?, for consistency, i.e. these escaped forms should be treated the same as their quoted equivalents, '*' / "*" and '?' / "?", because the intent to treat * and ? verbatim is expressed by all of these forms.

    I do realize that this complicates matters, because an argument such as a`*b* would then have to treat the first * verbatim, while retaining the second one as a globbing metacharacter; expressed in Bash terms, it would have to be treated as a\*b*for globbing purposes.

  10. SteveL-MSFT commented on Sep 12, 2022

    @SteveL-MSFT
    Member

    cc James Truher (@JamesWTruher)

    It seems reasonable that `"` is a single literal double quote that * is a single literal asterisk. /bin/echo "*" does do what you expect.

  11. JamesWTruher commented on Sep 13, 2022

    @JamesWTruher
    Collaborator

    FWIW, this is behavior is in ps6 as well.

  12. microsoft-github-policy-service commented on Nov 15, 2023

    @microsoft-github-policy-service
    Contributor

    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.

  13. microsoft-github-policy-service commented on Nov 15, 2023

    @microsoft-github-policy-service
    Contributor

    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.

  14. microsoft-github-policy-service commented on Nov 15, 2023

    @microsoft-github-policy-service
    Contributor

    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.

  15. microsoft-github-policy-service commented on Nov 22, 2023

    @microsoft-github-policy-service
    Contributor

    This issue has been marked as "No Activity" as there has been no activity for 6 months. It has been closed for housekeeping purposes.

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.Resolution-No ActivityIssue has had no activity for 6 months or more

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions