7

PowerShell の構文ifは次のとおりです。

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

もう 1 つの構文規則は、部分式の場合、次のように括弧を使用する必要があるというものです。

 write-output (get-date)

したがって、これら 2 つのルールを組み合わせると、いくつかのパスのテストは、次のように 2 組の括弧で記述する必要があると予想されます。

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

ただし、これも機能します。

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

完全を期すために、これは機能しません

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

(ここでは、通常どおり部分式を括弧で囲む必要があります)。

ここで適用される構文規則と、1 つの括弧だけで IF テストを使用できる理由を説明できる人はいますか? PowerShell マジックですか、それとも基本的な構文規則を誤解していますか?

4

2 に答える 2

4

Bruce Payette のWindows PowerShell in Actionの付録 C: The PowerShell grammar のC.2.2 を参照すると、次のようになります。

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

これは、ステートメントを認識するためのリテラル構文の一部として(とトークンを示し、ドキュメントの がブール値に解決されるパイプラインを参照していることを示しています。)if<test>about_If

パイプラインのルールに従うと、次のことがわかります。

  • Test-Path ...<cmdletCall>のにパースします<name> <parameterArgumentToken>
  • !Test-Path ...コマンドレットの呼び出しが単純なプロパティまたは配列規則と一致しない場合、これは失敗し<expressionRule>ます。<UnaryOperatorToken> <propertyOrArrayReferenceRule>
  • !(Test-Path ...)かっこで囲まれたコマンドレット呼び出しをサブ式として一致させることができます。

編集:PowerShell 2.0言語仕様も参照してください(別の質問に対するRomanの回答に感謝します)。

于 2012-06-17T21:21:39.830 に答える
3

if部分式を定義する後の括弧( の周りTest-Pathに括弧が必要な場合は、他のすべての式の周りに括弧が必要$num -eq 5です). not 演算子の後の追加の括弧は、Test-Path否定する前に評価する必要があるため必要です。if ステートメントなしでこれを試すことができます。

これは動作しません:

PS> !Test-Path NonExistent.file

これは機能します:

PS> !(Test-Path NonExistent.file)
于 2012-04-12T13:35:11.853 に答える