-
Notifications
You must be signed in to change notification settings - Fork 8.1k
Description
Following a conversation with @SteveL-MSFT where he confirmed I am not (entirely) insane 😜
PowerShell currently makes if VERY difficult to
- Specify that an arbitrary set of command-line args gets passed to an exe, verbatim
- That the same command-line also supports PowerShell command chaining, etc.
For example, trying to pass a Linux command-line cd / && ls . | cowsay to wsl in PowerShell 7+:
wsl cd / && ls .Expected: Directory listing of the root of the users' default Linux distro
Actual: Error reporting that cowsay is not a recognized command:

Note: to perform the above command, you'll need to enable WSL and a Linux distro. Within your default distro, you'll also need to install
cowsayvia your distro's package manager. For Ubuntu and Debian, you can do this viasudo apt install cowsay
As can be seen from the syntax color highlighting, PowerShell is parsing && as a PowerShell command continuation, not as a part of the command to be passed to wsl.
So, how about wrapping the args in quotes?

Doesn't work because that would make arg[1] 'cd / && ls . | cowsay' which wouldn't make sense to bash.
@SteveL-MSFT recommended prefixing the command-line args with --% to indicate that PowerShell should pass the remaining command-line verbatim. Alas, no joy here - notice the syntax highlighting which indicates that the parser thinks the && is a PowerShell command which, in this case, it is not!

Boo! 😟
Okay, so how about escaping the && with a ````` (backtick)?

Oh! PowerShell thinks that I meant to spawn the remaining command as a job. NOPE!
Closer!
Now, how about also escaping the pipe operator:

HUZZAH! 🙌
Escaping many symbols in lengthy command-lines could get tedious pretty quickly, especially when pasting more lengthy & complex bash command-lines into WSL, or complex page splits into wt (Windows Terminal):

While --% may be useful (when fixed) in some cases to pass the remainder of this command-line to the tool being executed, commands couldn't be chained.
So, ideally, PowerShell should (also) provide a way of escaping a specific portion of a command-line to the preceding tool, but then continue treating the remaining command-line as PowerShell script.
Perhaps enclosing the command-line segment in some of the following delimiters would work?
- Pointy-braces:
<...>, e.g.wsl <cd / && ls . | cowsay> - Square-braces:
[...], e.g.wsl [cd / && ls . | cowsay] - Curly-braces:
{...}, e.g.wsl {cd / && ls . | cowsay} - Double-backticks
- Arrow:
<--...--<<<, e.g.wsl <-- cd / && ls . | cowsay --<<<😜
... but will leave the choice of the enclosing delimiters to the language designers 😁
