ja-JP/about_Pipeline_Chain_Operators.help.txt

TOPIC
    about_Pipeline_Chain_Operators

簡単な説明
    PowerShell でパイプラインを && 演算子と || 演算子で連結する方法に
    ついて説明します。
    (PSHelpJaJP 日本語パッチ版)

詳細な説明
    PowerShell 7 以降では、パイプラインを条件付きで連結するための
    && 演算子と || 演算子が実装されています。これらの演算子は
    PowerShell では「パイプライン連結演算子」と呼ばれ、bash、zsh、sh
    などの POSIX シェルにおける AND-OR リストや、Windows コマンド
    シェル (cmd.exe) における条件処理記号と似ています。

    && 演算子は、左側のパイプラインが成功した場合に右側のパイプライン
    を実行します。逆に || 演算子は、左側のパイプラインが失敗した場合
    に右側のパイプラインを実行します。

    これらの演算子は、$? 変数と $LASTEXITCODE 変数を使ってパイプライン
    が失敗したかどうかを判断します。そのため、コマンドレットや関数だけ
    でなく、ネイティブコマンドと組み合わせて使うこともできます。
    たとえば次のとおりです。

        # Create an SSH key pair - if successful copy the public key to clipboard
        ssh-keygen -t rsa -b 2048 && Get-Content -Raw ~\.ssh\id_rsa.pub | clip

    例
        2 つのコマンドがどちらも成功する場合

            Write-Output 'First' && Write-Output 'Second'

            First
            Second

        最初のコマンドが失敗し、2 つ目が実行されない場合

            Write-Error 'Bad' && Write-Output 'Second'

            Write-Error: Bad

        最初のコマンドが成功するため、2 つ目のコマンドが実行されない
        場合

            Write-Output 'First' || Write-Output 'Second'

            First

        最初のコマンドが失敗するため、2 つ目のコマンドが実行される
        場合

            Write-Error 'Bad' || Write-Output 'Second'

            Write-Error: Bad
            Second

    パイプラインの成否は $? 変数の値によって決まります。$? は、
    パイプラインの実行状態に基づいて、パイプラインの実行後に PowerShell
    が自動的に設定します。つまり、パイプライン連結演算子には次のような
    等価性があります。

        Test-Command '1' && Test-Command '2'

    は、次と同じ動作になります。

        Test-Command '1'; if ($?) { Test-Command '2' }

    また、

        Test-Command '1' || Test-Command '2'

    は、次と同じ動作になります。

        Test-Command '1'; if (-not $?) { Test-Command '2' }

    パイプライン連結からの代入
        パイプライン連結から変数に代入すると、連結内のすべての
        パイプラインを連結した結果が代入されます。

            $result = Write-Output '1' && Write-Output '2'
            $result

            1
            2

        パイプライン連結からの代入中にスクリプトを終了させるエラーが
        発生した場合、代入は成功しません。

            try
            {
                $result = Write-Output 'Value' && $(throw 'Bad')
            }
            catch
            {
                # Do nothing, just squash the error
            }

            "Result: $result"

            Result:

    演算子の構文と優先順位
        他の演算子とは異なり、&& と || は、たとえば + や -and のような
        式ではなく、パイプラインを対象に動作します。

        && と || は、パイプ (|) やリダイレクト (>) より優先順位が低い
        一方で、ジョブ演算子 (&)、代入 (=)、セミコロン (;) よりは
        優先順位が高くなります。つまり、パイプライン連結内の各
        パイプラインを個別にリダイレクトでき、パイプライン連結全体を
        バックグラウンドで実行したり、変数に代入したり、ステートメント
        として区切ったりできます。

        パイプライン連結内で優先順位の低い構文を使うには、丸括弧 (...)
        の使用を検討してください。同様に、パイプライン連結内に
        ステートメントを埋め込むには、サブ式 $(...) を使用できます。
        これは、ネイティブコマンドを制御フローと組み合わせる場合に
        役立ちます。

            foreach ($file in 'file1','file2','file3')
            {
                # When find succeeds, the loop breaks
                find $file && Write-Output "Found $file" && $(break)
            }

            find: file1: No such file or directory
            file2
            Found file2

        PowerShell 7 では、これらの構文の動作が変更され、丸括弧内や
        サブ式内でコマンドが成功または失敗したときに、$? が期待どおり
        に設定されるようになりました。

        PowerShell の他のほとんどの演算子と同様に、&& と || も
        「左結合」であり、左からグループ化されます。たとえば次の
        とおりです。

            Get-ChildItem -Path ./file.txt ||
                Write-Error "file.txt doesn't exist" &&
                Get-Content -Raw ./file.txt

        これは次のようにグループ化されます。

            (Get-ChildItem -Path ./file.txt || Write-Error "file.txt doesn't exist") &&
                Get-Content -Raw ./file.txt

        これは次と等価です。

            Get-ChildItem -Path ./file.txt

            if (-not $?) { Write-Error "file.txt does not exist" }

            if ($?) { Get-Content -Raw ./file.txt }

    エラーとの相互作用
        パイプライン連結演算子はエラーを吸収しません。パイプライン連結
        内のステートメントがスクリプトを終了させるエラーをスローすると、
        パイプライン連結は終了します。

        たとえば次のとおりです。

            $(throw 'Bad') || Write-Output '2'

            Exception: Bad

        エラーがキャッチされた場合でも、パイプライン連結は終了します。

            try
            {
                $(throw 'Bad') || Write-Output '2'
            }
            catch
            {
                Write-Output "Caught: $_"
            }
            Write-Output 'Done'

            Caught: Bad
            Done

        エラーが非終了エラーであるか、パイプラインのみを終了させる
        ものである場合、パイプライン連結は $? の値を尊重して継続
        します。

            function Test-NonTerminatingError
            {
                [CmdletBinding()]
                param()

                $exception = [System.Exception]::new('BAD')
                $errorId = 'BAD'
                $errorCategory = 'NotSpecified'

                $errorRecord = [System.Management.Automation.ErrorRecord]::new(
                    $exception, $errorId, $errorCategory, $null
                )

                $PSCmdlet.WriteError($errorRecord)
            }

            Test-NonTerminatingError || Write-Output 'Second'

            Test-NonTerminatingError: BAD
            Second

    コマンドではなくパイプラインを連結する
        パイプライン連結演算子は、その名前のとおり、単にコマンドだけ
        でなくパイプラインも連結できます。これは他のシェルの動作と
        一致しますが、成否の判断を難しくする場合があります。

            function Test-NotTwo
            {
                [CmdletBinding()]
                param(
                  [Parameter(ValueFromPipeline)]
                  $Input
                )

                process
                {
                    if ($Input -ne 2)
                    {
                        return $Input
                    }

                    $exception = [System.Exception]::new('Input is 2')
                    $errorId = 'InputTwo'
                    $errorCategory = 'InvalidData'

                    $errorRecord = [System.Management.Automation.ErrorRecord]::new(
                        $exception, $errorId, $errorCategory, $null
                    )

                    $PSCmdlet.WriteError($errorRecord)
                }
            }

            1,2,3 | Test-NotTwo && Write-Output 'All done!'

            1
            Test-NotTwo : Input is 2
            3

        Test-NotTwo は非終了エラーを生成した後に失敗したとみなされる
        ため、Write-Output 'All done!' は実行されない点に注意して
        ください。

関連項目
    about_Automatic_Variables
    about_Operators
    about_Pipelines

----
原文: PowerShell-Docs (CC BY 4.0) の翻訳 / PSHelpJaJP