Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does PowerShell split arguments containing hyphens and periods?

In a PowerShell window:

PS C:\> echo -abc.def.ghi
-abc
.def.ghi

For some reason, the combination of a hyphen and period cause Powershell to split the argument into two lines.

It does not occur with without the hyphen:

PS C:\> echo abc.def.ghi
abc.def.ghi

Nor does it occur when there are no periods:

PS C:\> echo -abcdefghi
-abcdefghi

Through experimentation, I've found I can escape the behavior with a backtick:

PS C:\> echo `-abc.def.ghi
-abc.def.ghi

But why does this occur? What fundamental part of PowerShell syntax am I not understanding?

like image 669
Matt Johnson-Pint Avatar asked Feb 24 '15 19:02

Matt Johnson-Pint


2 Answers

I've disassembled Microsoft.PowerShell.Utility to look at the code of Write-Output nothing special there, it just iterates through InputObject and passes each to a WriteObject method implemented by the current ICommandRuntime.

Disassembled <code>Write-Output</code>

My guess is that the tokenizer that process the text tries to match anything starting with a - to a declared parameter. Failing that, it passes it through the pipeline as an item in -InputObject. Since a . cannot be a part of a variable name and therefore can't be part of a switch name it might separate it before doing the if check and when it turns out to be a parameter it doesn't join it back up with the rest of the token. You might therefore have found a minor bug.

When using the back tick or quotation marks it doesn't make this mistake however since it can tokenize the entire thing.

This is all conjecture though, I'd love to see a authoritative answer as much as you.

Edit

Evidence of what I'm saying:

PS> echo -NoEnumerate.foo
.foo
like image 103
George Mauer Avatar answered Dec 08 '22 22:12

George Mauer


FYI not sure if George was trying to mention this or not but echo is an alias for Write-Output in PowerShell.

PS C:\temp> Get-Alias echo

CommandType     Name                                               ModuleName                                                                                
-----------     ----                                               ----------                                                                                
Alias           echo -> Write-Output       

In the example echo -abc.def.ghi the parser sees the unquoted hyphen as the prefix for a parameter/switch name. Period also has special meaning. Parameters cannot contain periods so the parser is treating that like the string terminator.

As a whole write-output sees it as an array so it is matched positionally to -InputObject

(I hope i'm not totally wrong with my assertions.)

like image 44
Matt Avatar answered Dec 09 '22 00:12

Matt