2015-02-24 14 views
6

W oknie PowerShell:Dlaczego PowerShell dzieli argumenty zawierające łączniki i kropki?

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

Z jakiegoś powodu, połączenie z myślnikiem i okresu przyczyny PowerShell podzielić argumentu na dwie linie.

To nie wystąpić bez myślnika:

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

Nie ma ona wystąpić, gdy nie istnieją żadne okresy:

PS C:\> echo -abcdefghi 
-abcdefghi 

Poprzez eksperymentowanie, Znalazłem mogę uciec z zachowania grawis:

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

Ale dlaczego łania to się dzieje? Jaka fundamentalna część składni PowerShell nie rozumiem?

+1

Hmm, ciekawe. Zwracam uwagę na "echo" -abc.def "' działa zgodnie z oczekiwaniami, więc może to być podpowiedź –

+1

Zakładając, że używasz PowerShell V3 +, możesz użyć tego '{echo -abc.def.ghi} .Ast.EndBlock.Statements [0] .PipelineElements [0] .CommandElements ', aby zobaczyć, jak interpretuje to parser: – PetSerAl

Odpowiedz

5

Mam zdemontowany Microsoft.PowerShell.Utility spojrzeć na kod Write-Output tam nic specjalnego, po prostu iteracji InputObject i przechodzi każdy z WriteObject sposobu realizowanego przez obecnego ICommandRuntime.

Disassembled <code>Write-Output</code>

Domyślam się, że tokenizer który przetwarza tekst stara się dopasować wszystko począwszy - do deklarowanych parametrów. W przeciwnym razie przechodzi przez rurociąg jako element w pozycji -InputObject. Ponieważ . nie może być częścią nazwy zmiennej i dlatego nie może być częścią nazwy przełącznika, może oddzielić ją przed wykonaniem sprawdzenia if, a gdy okaże się parametrem, do którego nie dołącza, resztę tokena. Możliwe, że znalazłeś drobny błąd.

Używając wstecznego znacznika lub cudzysłowu, nie popełnia tego błędu, ponieważ może on tokenizować całą rzecz.

Jest to jednak przypuszczenie, chciałbym zobaczyć autorytatywną odpowiedź tak samo jak ty.

Edit

Dowody co mówię:

+1

' .' może być częścią nazwy zmiennej: '$ {Prawie każdy znak może być częścią nazwy zmiennej.}'. – PetSerAl

+0

@PetSerAl no tak, ale nie bez nawiasów klamrowych, więc mój Argument nadal obowiązuje, ale dobry punkt, –

+0

To nie jest błąd, to funkcja. "command -s. \ localfile' następnie robi to, co chcesz.To samo zachowanie występuje dla' command -s: localfile', ale nie dla 'polecenia -s # localfile'. –

1
nie

FYI pewien, czy George starał się wspomnieć o tym, czy nie, ale echo jest aliasem dla Write-Output w PowerShell.

PS C:\temp> Get-Alias echo 

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

W przykładzie echo -abc.def.ghi parsera widzi niecytowany myślnik jako przedrostek nazwy parametru/przełącznika. Okres ma również specjalne znaczenie. Parametry nie mogą zawierać kropek, więc parser traktuje to tak jak terminator ciągu znaków.

Jako całość write-output widzi go jako tablicę więc jest dopasowana pozycyjnie do -InputObject

(mam nadzieję, że nie jestem całkowicie błędne z moich twierdzeń.)

+0

Więc bez myślnika jest to * nie * za parametr? –

+1

Nie będzie próbował go dopasować. Po prostu próbowałby to przypisać w tym miejscu. Ja też nie próbowałbym analizować okresów. Dlatego cytowanie jest dobrą praktyką. – Matt

+1

Sprzeciwiam się zbyt wielu Matkom! –