-
Notifications
You must be signed in to change notification settings - Fork 8.1k
Description
See also: #15250, #15261, #15276 - see overview in #15143.
The new-in-preview.5 PSNativeCommandArgumentPassing experimental feature aims to fix the longstanding problem with passing arguments to external programs, notably arguments with embedded " chars. and empty-string arguments. (see #1995 (comment) for a summary of the previously required workarounds; #14692 is the PR that implemented the experimental feature).
The experimental feature:
-
fully fixes the problem on Unix-like platforms.
-
partially fixes it on Windows, because vital accommodations for high-profile CLIs are missing - see Implement accommodations for Windows CLIs, notably batch files and misexec-style programs as part of experimental feature PSNativeCommandArgumentPassing #15143
-
breaks
cmd /c(cmd /k) calls, where a command line forcmd.exeis passed as a single string - which is a common workaround for the problems with the previous behavior (see Use ArgumentList when invoking native executables #14747 (comment))
As explained in #14747 (comment), the old, broken behavior must be retained in this very specific scenario, because cmd.exe actually requires this broken behavior.
Steps to reproduce
Note: To see the problem, you must use PowerShell Core 7.2.0-preview.5, with experimental feature PSNativeCommandArgumentPassing enabled and preference variable $PSNativeCommandArgumentPassing set to 'Standard' (the default).
cmd /c 'echo "3"'
cmd /c "echo `"$(1+2)`""(Note that cmd.exe's internal echo command retains double-quoting as passed on the command line.)
Expected behavior
"3"
"3"
This is the old - and in this exceptional case correct - behavior.
Actual behavior
\"3\"
\"3\"
Embedded " chars. were passed escaped as \" - while this is generally the right thing to do, it isn't when calling cmd /c or cmd /k with a command line passed as a single string.
Environment data
PowerShell Core 7.2.0-preview.5