Description
Problem Statement
Currently, there are cases where cutting and pasting a native command line fails to run as expected in PowerShell. This may be due to incorrect parsing of quotes meant to be passed to the native command or use of PowerShell syntax that is not meant to be interpreted as PowerShell. PowerShell has a --%
special argument when used with native commands treats the rest of the arguments as literals passed to the native command, but has several issues:
- It is not discoverable, users need to know about this special parameter ahead of time
|
,&&
, and||
take precedence, so:wsl --% ls | less
would executewsl ls
and pipe the results toless
running in PowerShell rather thanless
running in wsl- If you cut and paste a command line, you would need to edit the line to insert
--%
towards the beginning - On Unix systems, the args after --% are passed verbatim w/o globbing where native commands on Unix expect the shell to perform globbing
Proposed technical implementation details
Proposal is to introduce a new --%
(Call Native) operator.
Any text content after this operator will call into the "default shell" of the OS to execute. On Windows, this would be cmd.exe and on Unix-based systems this would be /bin/sh. This resolves the globbing issue on Unix-based systems, and also allow %variable%
expansion on Windows. Unlike --%
switch, this also means that |
, &&
, and ||
are treated as part of the native command line.
This means that these two are functionally the same:
wsl --% ls $foo `&`& echo $PWD
--% wsl ls $foo && echo $PWD
where $foo
and $PWD
is evaluated by the shell within WSL. Note that in the first example, you would have to know to escape &&
to have it execute within WSL instead of within PowerShell.
To pipe output from such execution back into PowerShell, the user is required to store the results into a variable first:
$out = --% ls *.txt
$out | select-string hello
Note that unlike the current &
call operator, you cannot use any PowerShell syntax, so:
--% $commandline
would not resolve $commandline
as a variable first by PowerShell, but instead pass $commandline
to the default shell to process unresolved.
The cut & paste problem is solved by simply pasting after --%
is typed.
The above example for wsl would look like:
--% wsl ls | less
where the intent is to have that whole line execute within the WSL Linux instance.
Discoverability
Users already familiar with --%
as a switch may easily transition to using this new operator where it makes sense. For new users, --%
is unique so that search engines find it easily related to PowerShell.
Alternate Considerations
&!
and &n
were proposed as the sigil, but there was push back because &!
is a valid operator in some languages making a web search for documentation more difficult. There was also a concern whether visual similar to &
call operator would be confusing to users.
There is question about supporting line-continuation when using this new operator. I would suggest that we do not support it initially.
A cmdlet solution instead of an operator solution was proposed. We believe this doesn't solve the "cut & paste" problem as now you need to know to put the pipeline in single quotes and/or escape special characters. We do believe a cmdlet as in Invoke-NativeCommand
(noun to be determined) would be useful as an additional option instead of replacing the need for an operator.
Related issues
This should also solve these issues:
Metadata
Metadata
Assignees
Labels
Type
Projects
Status