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

Prerequisites

See also (the inverse problem): https://github.com/PowerShell/PowerShell/issues/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

About this issue

  • Original URL
  • State: closed
  • Created 2 years ago
  • Reactions: 1
  • Comments: 15 (11 by maintainers)

Most upvoted comments

  • PSNativeCommandArgumentPassing is incidental to this discussion, because in effect it only relates to " chars. embedded in arguments.
  • Use of --% is virtually pointless on Unix-like platforms (and documented as such - for the backstory, see https://github.com/MicrosoftDocs/PowerShell-Docs/issues/4963).

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.