Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PowerShell's call operator (&) syntax and double-quotes

Tags:

powershell

Can someone explain this result to me? I've wasted a lot of time over the years trying to master PowerShell's syntax for calling commands, but this...I can't even make a guess how to get this result from the input.

PS C:\Users\P> & echoargs "   ""1"" 2 3 ""4 5 6""   7 8 9"
Arg 0 is <   1 2 3 4>
Arg 1 is <5>
Arg 2 is <6   7 8 9>

Bueller?

like image 908
Peter Seale Avatar asked Jan 18 '12 04:01

Peter Seale


People also ask

What is call operator in PowerShell?

The call operator, also known as the "invocation operator", lets you run commands that are stored in variables and represented by strings or script blocks. The call operator executes in a child scope.

What does $_ mean in PowerShell?

The “$_” is said to be the pipeline variable in PowerShell. The “$_” variable is an alias to PowerShell's automatic variable named “$PSItem“. It has multiple use cases such as filtering an item or referring to any specific object.

What does $() mean in PowerShell?

The $() is the subexpression operator. It causes the contained expressions to be evaluated and it returns all expressions as an array (if there is more than one) or as a scalar (single value).


2 Answers

The doubled-up doubles quotes inside a double-quoted string is a way to insert a double quote. The updated version of echoargs.exe shows this a bit more clearly as it shows you the command line used to invoke the exe:

PS>  echoargs "   ""1"" 2 3 ""4 5 6""   7 8 9"
Arg 0 is <   1 2 3 4>
Arg 1 is <5>
Arg 2 is <6   7 8 9>

Command line:
"C:\...\Modules\Pscx\Apps\EchoArgs.exe"  "   "1" 2 3 "4 5 6"   7 8 9"

If you take that command line (after it has been parsed by PowerShell) you get the same result in CMD.exe:

CMD> EchoArgs.exe "   "1" 2 3 "4 5 6"   7 8 9"
Arg 0 is <   1 2 3 4>
Arg 1 is <5>
Arg 2 is <6   7 8 9>

Command line:
C:\...\Modules\Pscx\Apps\EchoArgs.exe  "   "1" 2 3 "4 5 6"   7 8 9"

As to why .NET or the C++ startup code parses the command line that way, I'm not entirely sure. This MSDN topic covers it a bit and if you look at the examples at the bottom of the topic, you will see some equally weird parsing behavior e.g. a\\\b d"e f"g h gives a\\\b, de fg and h.

like image 74
Keith Hill Avatar answered Nov 03 '22 02:11

Keith Hill


Note that Powershell is known for some heavy bugs when it comes to passing arguments to applications and quoting the said arguments - http://connect.microsoft.com/PowerShell/feedback/details/376207/executing-commands-which-require-quotes-and-variables-is-practically-impossible

This is how I understand how it is being (mis)parsed:

The string is " ""1"" 2 3 ""4 5 6"" 7 8 9"

Because of the bug the double double quotes, which become literal double quote, never make it.

The string would be like " "1" 2 3 "4 5 6" 7 8 9"

So <space>1 2 3 4 becomes an argument because it the first section with matching quotes and 4 occurs before the next space. Then space, and hence 5 becomes second argument. Then space, so the next part will be a separate argument. Here again, the same rule as the first argument, except that 6 occurs before quote and without a space and hence 6 7 8 9 becomes the next argument.

Bottomline - Powershell argument passing to external applications is pretty messed up.

like image 40
manojlds Avatar answered Nov 03 '22 02:11

manojlds