Remarque
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de vous connecter ou de modifier des répertoires.
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de modifier des répertoires.
Brève description
Décrit les pipelines de chaînage avec les opérateurs && et || dans PowerShell.
Description longue
À compter de PowerShell 7, PowerShell implémente les opérateurs && et || pour chaîner des pipelines de manière conditionnelle. Ces opérateurs sont connus dans PowerShell comme opérateurs de chaîne de pipeline, et sont similaires à AND-OR listes dans des interpréteurs de commandes POSIX tels que bash, zsh et sh, ainsi que symboles de traitement conditionnel dans l’interpréteur de commandes Windows (cmd.exe).
L’opérateur && exécute le pipeline de droite, si le pipeline de gauche a réussi. À l’inverse, l’opérateur || exécute le pipeline de droite si le pipeline de 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 applets de commande 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 à celle de la piping (|) ou de 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é afin que $? soit défini comme prévu lorsqu’une commande réussit ou échoue entre parenthèses ou sous-expressions.
Comme la plupart des autres opérateurs dans PowerShell, && et || sont également associatif 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, 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 que Write-Output 'All done!' n’est pas exécuté, car Test-NotTwo est considéré comme ayant échoué après avoir généré l’erreur de non-fin.