2012-04-12 22 views
6

W PowerShell składnia if jest tak:Skąd pochodzi `jeśli (Ścieżka testowa ...)` faktycznie działa?

if (<test1>) 
    {<statement list 1>} 
[elseif (<test2>) 
    {<statement list 2>}] 
[else 
    {<statement list 3>}] 

Kolejna reguła składnia jest dla podwyrażeń, trzeba użyć nawiasów tak:

write-output (get-date) 

Więc z tych dwóch reguły w połączeniu, oczekiwałbym, że test dla pewnej ścieżki musi być napisany z dwoma zestawami nawiasów takich jak ten:

if ((Test-Path ...)) { 
    # do something 
} 

Jednak ta działa również:

if (Test-Path ...) { 
    # do something 
} 

i tylko ze względu na kompletność, to nie praca:

if (!Test-Path ...) { 
    # do something 
} 

(tu trzeba by zawinąć podwyrażenie w nawiasie jak zwykle).

Czy ktoś może wyjaśnić zasady składni, które mają tu zastosowanie i dlaczego mogę użyć testu IF tylko z jednym nawiasem? Czy to jest jakaś magia PowerShell, czy też nie rozumiem podstawowych zasad składni?

Odpowiedz

3

Nawiązując do C.2.2 z Appendix C: The PowerShell grammar w Bruce Payette na Windows PowerShell in Action, mamy:

<ifStatementRule> = 
    'if' '(' <pipelineRule> ')' <statementBlockRule> 
    [ 'elseif' '(' <pipelineRule> ')' <statementBlockRule> ]* 
    [ 'else' <statementBlockRule> ]{0|1} 

ten wskazuje tokeny ( i ) jako część składni literalnej do rozpoznawania instrukcji if i że dokumentacja <test> z dokumentacji about_If odnosi się do potoku, który zostanie przetłumaczony na wartość logiczną.

Zgodnie z zasadami rurociąg, znajdziemy:

  • Test-Path ... analizuje Do <cmdletCall> od <name> <parameterArgumentToken>,
  • !Test-Path ... wyniki w <expressionRule> z <UnaryOperatorToken> <propertyOrArrayReferenceRule>, który zawodzi, gdy rozmowa cmdlet nie może się równać z prostą własność lub tablicę reguła, podczas gdy
  • !(Test-Path ...) jest w stanie dopasować nawiasy w nawiasach jako podekspresję.

EDIT: Zobacz również PowerShell 2.0 Language Specification (dzięki Roman's answer to another question).

3

Nawiasy po if definiują podwyrażenie (jeśli nawiasy wymagano około Test-Path, to wtedy trzeba nawiasów około $num -eq 5 i wszystkie inne wyrażenia) .. Dodatkowe nawiasach po operator nie jest wymagane, ponieważ Test-Path musi być ocenione przed może być zanegowane. Możesz spróbować tego bez instrukcji if.

To nie działa:

PS> !Test-Path NonExistent.file 

to działa:

PS> !(Test-Path NonExistent.file) 
+0

Spróbuj tego: 'if true'. Da Ci to błąd * parsera *. Nie jestem ekspertem, ale wydaje mi się, że nawiasy są tutaj konstruktem języka, a nie operatorem podwyrażania. – Borek

+0

@Borek: W PowerShell myślę, że musisz napisać: , jeśli $ True – wunth

Powiązane problemy