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?
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.
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.
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).
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
.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With