2012-04-12 15 views
6

En PowerShell, sintaxis para if es tan así:¿Cómo funciona `if (Test-Path ...)` realmente funciona?

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

Otra regla de sintaxis es que para subexpresiones, es necesario utilizar paréntesis así:

write-output (get-date) 

Así que con estos dos reglas combinadas, esperaría que la prueba para alguna ruta se deba escribir con dos conjuntos de paréntesis como este:

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

Sin embargo, esto también funciona:

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

y sólo por la mayor abundamiento, este no trabajo:

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

(aquí, lo que se necesita para envolver la subexpresión entre paréntesis, como de costumbre).

¿Alguien puede explicar las reglas de sintaxis que se aplican aquí y cómo puede utilizar la prueba IF solo con un paréntesis? ¿Es alguna magia de PowerShell o estoy malinterpretando las reglas básicas de sintaxis?

Respuesta

3

Refiriéndose a partir de C.2.2 Appendix C: The PowerShell grammar en Bruce Payette de Windows PowerShell in Action, tenemos:

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

Este indica los tokens ( y ) como parte de la sintaxis literal para reconocer una declaración if, y que la <test> de la documentación about_If se refiere a una canalización que se resolverá en un booleano.

Siguiendo las reglas de tuberías, encontramos:

  • Test-Path ... un análisis sintáctico a un <cmdletCall> de <name> <parameterArgumentToken>,
  • !Test-Path ... resultados en una <expressionRule> de <UnaryOperatorToken> <propertyOrArrayReferenceRule>, que falla cuando la llamada cmdlet no puede coincidir con la propiedad sencilla o matriz regla, mientras que
  • !(Test-Path ...) puede hacer coincidir la llamada de cmdlets entre paréntesis como una sub-expresión.

Editar: Véase también PowerShell 2.0 Language Specification (gracias a Roman's answer to another question).

3

Los paréntesis después del if definen una subexpresión (si se requiere paréntesis alrededor Test-Path, entonces necesitaríamos alrededor de parens $num -eq 5 y todas las demás expresiones ..) Los paréntesis adicionales después de que se requiere que el operador no porque Test-Path necesita ser evaluado antes puede ser negado Puede probar esto sin una instrucción if.

Esto no funciona:

PS> !Test-Path NonExistent.file 

Esto funciona:

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

Prueba esto: 'if true'. Le dará un error * analizador *. No soy un experto, pero me parece que los paréntesis son aquí una construcción del lenguaje, no un operador de subexpresión. – Borek

+0

@Borek: en PowerShell creo que lo que tendría que escribir es si $ True – wunth

Cuestiones relacionadas