about_Pipeline_Chain_Operators
Description courte
Décrit les pipelines de chaînage avec les opérateurs et ||
les &&
opérateurs dans PowerShell.
Description longue
À compter de PowerShell 7, PowerShell implémente les opérateurs et ||
les &&
implémente sur des pipelines de chaîne conditionnelle. Ces opérateurs sont connus dans PowerShell en tant qu’opérateurs de chaîne de pipeline et sont similaires aux listes AND-OR dans des interpréteurs de commandes POSIX tels que bash, zsh et sh, ainsi que des symboles de traitement conditionnel dans l’interpréteur de commandes Windows (cmd.exe).
L’opérateur &&
exécute le pipeline droit si l’exécution du pipeline gauche a réussi. Inversement, l’opérateur ||
exécute le pipeline droit si l’exécution du pipeline gauche a échoué.
Ces opérateurs utilisent les variables $?
et $LASTEXITCODE
pour déterminer si un pipeline a échoué. Cela vous permet de les utiliser avec des commandes natives, et pas seulement avec des cmdlet ou des fonctions. Par exemple :
# 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
Exemples
Deux commandes réussies
Write-Output 'First' && Write-Output 'Second'
First
Second
La première commande échoue, ce qui entraîne l’exécution de la seconde
Write-Error 'Bad' && Write-Output 'Second'
Write-Error: Bad
La première commande réussit, de sorte que la deuxième commande n’est pas exécutée
Write-Output 'First' || Write-Output 'Second'
First
La première commande échoue, de sorte que la deuxième commande est exécutée
Write-Error 'Bad' || Write-Output 'Second'
Write-Error: Bad
Second
La réussite du pipeline est définie par la valeur de la $?
variable, que PowerShell définit automatiquement après l’exécution d’un pipeline en fonction de son état d’exécution.
Cela signifie que les opérateurs de chaîne de pipeline ont l’équivalence suivante :
Test-Command '1' && Test-Command '2'
fonctionne de la même façon que
Test-Command '1'; if ($?) { Test-Command '2' }
et
Test-Command '1' || Test-Command '2'
fonctionne de la même façon que
Test-Command '1'; if (-not $?) { Test-Command '2' }
Affectation à partir de chaînes de pipeline
L’affectation d’une variable à partir d’une chaîne de pipeline prend la concaténation de tous les pipelines de la chaîne :
$result = Write-Output '1' && Write-Output '2'
$result
1
2
Si une erreur de fin de script se produit pendant l’affectation à partir d’une chaîne de pipeline, l’affectation ne réussit pas :
try
{
$result = Write-Output 'Value' && $(throw 'Bad')
}
catch
{
# Do nothing, just squash the error
}
"Result: $result"
Result:
Syntaxe et précédence des opérateurs
Contrairement à d’autres opérateurs, &&
et ||
fonctionnent sur des pipelines, plutôt que sur des expressions comme +
ou -and
, par exemple.
&&
et ||
ont une priorité inférieure à la canalisation (|
) ou à la redirection (>
), mais une priorité plus élevée que les opérateurs de travail (&
), l’affectation (=
) ou les points-virgules (;
). Cela signifie que les pipelines au sein d’une chaîne de pipeline peuvent être redirigés individuellement et que l’ensemble des chaînes de pipeline peuvent être en arrière-plan, affectées à des variables ou séparées en tant qu’instructions.
Pour utiliser la syntaxe de précédence inférieure au sein d’une chaîne de pipeline, envisagez l’utilisation de parenthèses (...)
. De même, pour incorporer une instruction dans une chaîne de pipeline, une sous-expression $(...)
peut être utilisée. Cela peut être utile pour combiner des commandes natives avec un flux de contrôle :
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
À compter de PowerShell 7, le comportement de ces syntaxes a été modifié de sorte qu’il $?
soit défini comme prévu lorsqu’une commande réussit ou échoue entre parenthèses ou sous-expression.
Comme la plupart des autres opérateurs dans PowerShell, &&
et ||
sont également associatifs de gauche, ce qui signifie qu’ils regroupent à partir de la gauche. Par exemple :
Get-ChildItem -Path ./file.txt ||
Write-Error "file.txt doesn't exist" &&
Get-Content -Raw ./file.txt
regroupera comme suit :
(Get-ChildItem -Path ./file.txt || Write-Error "file.txt doesn't exist") &&
Get-Content -Raw ./file.txt
équivaut à :
Get-ChildItem -Path ./file.txt
if (-not $?) { Write-Error "file.txt does not exist" }
if ($?) { Get-Content -Raw ./file.txt }
Interaction d’erreur
Les opérateurs de chaîne de pipeline n’absorbent pas les erreurs. Lorsqu’une instruction d’une chaîne de pipeline lève une erreur de fin de script, la chaîne de pipeline est arrêtée.
Par exemple :
$(throw 'Bad') || Write-Output '2'
Exception: Bad
Même lorsque l’erreur est interceptée, la chaîne de pipeline est toujours arrêtée :
try
{
$(throw 'Bad') || Write-Output '2'
}
catch
{
Write-Output "Caught: $_"
}
Write-Output 'Done'
Caught: Bad
Done
Si une erreur n’est pas terminée ou termine uniquement un pipeline, la chaîne de pipeline continue, en respectant la valeur de $?
:
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
Chaînage de pipelines plutôt que de commandes
Les opérateurs de chaîne de pipeline, par leur nom, peuvent être utilisés pour chaîner des pipelines plutôt que des commandes. Cela correspond au comportement d’autres interpréteurs de commandes, mais peut rendre la réussite plus difficile à déterminer :
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
Notez qu’elle Write-Output 'All done!'
n’est pas exécutée, car Test-NotTwo
elle est considérée comme ayant échoué après avoir généré l’erreur de non-fin.
Voir aussi
Commentaires
https://aka.ms/ContentUserFeedback.
Bientôt disponible : Tout au long de 2024, nous allons supprimer progressivement GitHub Issues comme mécanisme de commentaires pour le contenu et le remplacer par un nouveau système de commentaires. Pour plus d’informations, consultezEnvoyer et afficher des commentaires pour