about_Pipeline_Chain_Operators
簡単な説明
PowerShell でパイプラインと演算子を&&
||
連結する方法について説明します。
詳細な説明
PowerShell 7 以降、PowerShell はパイプラインを &&
条件付きでチェーンするための and ||
演算子を実装します。 これらの演算子は、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' }
and
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
Write-Output 'All done!'
これは、終了しないエラーを生成した後に失敗したと見なされるためTest-NotTwo
、実行されないことに注意してください。
関連項目
PowerShell
フィードバック
https://aka.ms/ContentUserFeedback」を参照してください。
以下は間もなく提供いたします。2024 年を通じて、コンテンツのフィードバック メカニズムとして GitHub の issue を段階的に廃止し、新しいフィードバック システムに置き換えます。 詳細については、「フィードバックの送信と表示