about_Pipeline_Chain_Operators
Descrizione breve
Descrive il concatenamento delle pipeline con gli &&
operatori e ||
in PowerShell.
Descrizione lunga
A partire da PowerShell 7, PowerShell implementa gli &&
operatori e ||
per concatenare in modo condizionale le pipeline. Questi operatori sono noti in PowerShell come operatori della catena di pipeline e sono simili agli elenchi AND-OR nelle shell POSIX come bash, zsh e sh, nonché simboli di elaborazione condizionale nella shell dei comandi di Windows (cmd.exe).
L'operatore &&
esegue la pipeline di destra se la pipeline di sinistra ha avuto esito positivo. Viceversa, l'operatore ||
esegue la pipeline di destra se la pipeline di sinistra ha avuto esito negativo.
Questi operatori usano le variabili $?
e $LASTEXITCODE
per determinare se una pipeline ha avuto esito negativo. Ciò consente di usarli con comandi nativi e non solo con cmdlet o funzioni. Ad esempio:
# 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
Esempi
Due comandi riusciti
Write-Output 'First' && Write-Output 'Second'
First
Second
Il primo comando ha esito negativo, causando la mancata esecuzione del secondo
Write-Error 'Bad' && Write-Output 'Second'
Write-Error: Bad
Il primo comando ha esito positivo, quindi il secondo comando non viene eseguito
Write-Output 'First' || Write-Output 'Second'
First
Il primo comando ha esito negativo, quindi viene eseguito il secondo comando
Write-Error 'Bad' || Write-Output 'Second'
Write-Error: Bad
Second
L'esito positivo della pipeline è definito dal valore della $?
variabile, che PowerShell imposta automaticamente dopo l'esecuzione di una pipeline in base allo stato di esecuzione.
Ciò significa che gli operatori della catena di pipeline hanno l'equivalenza seguente:
Test-Command '1' && Test-Command '2'
funziona allo stesso modo di
Test-Command '1'; if ($?) { Test-Command '2' }
e
Test-Command '1' || Test-Command '2'
funziona allo stesso modo di
Test-Command '1'; if (-not $?) { Test-Command '2' }
Assegnazione da catene di pipeline
L'assegnazione di una variabile da una catena di pipeline accetta la concatenazione di tutte le pipeline nella catena:
$result = Write-Output '1' && Write-Output '2'
$result
1
2
Se si verifica un errore di terminazione dello script durante l'assegnazione da una catena di pipeline, l'assegnazione non riesce:
try
{
$result = Write-Output 'Value' && $(throw 'Bad')
}
catch
{
# Do nothing, just squash the error
}
"Result: $result"
Result:
Sintassi e precedenza degli operatori
A differenza di altri operatori e &&
||
operano su pipeline, anziché su espressioni come +
o -and
, ad esempio.
&&
e ||
hanno una precedenza inferiore rispetto al piping () o al reindirizzamento (|
>
), ma una precedenza maggiore rispetto agli operatori di processo (), l'assegnazione (&
=
) o il punto e virgola (;
). Ciò significa che le pipeline all'interno di una catena di pipeline possono essere reindirizzate singolarmente e che l'intera catena di pipeline può essere in background, assegnata a variabili o separate come istruzioni.
Per usare la sintassi di precedenza inferiore all'interno di una catena di pipeline, considerare l'uso delle parentesi (...)
. Analogamente, per incorporare un'istruzione all'interno di una catena di pipeline, è possibile usare una sottoespressione $(...)
. Ciò può essere utile per combinare comandi nativi con il flusso di controllo:
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
A partire da PowerShell 7, il comportamento di queste sintassi è stato modificato in modo che $?
venga impostato come previsto quando un comando riesce o non riesce tra parentesi o sottoespressione.
Come la maggior parte degli altri operatori in PowerShell &&
, e ||
sono anche associati a sinistra, ovvero raggruppano da sinistra. Ad esempio:
Get-ChildItem -Path ./file.txt ||
Write-Error "file.txt doesn't exist" &&
Get-Content -Raw ./file.txt
verrà raggruppato come:
(Get-ChildItem -Path ./file.txt || Write-Error "file.txt doesn't exist") &&
Get-Content -Raw ./file.txt
equivale a:
Get-ChildItem -Path ./file.txt
if (-not $?) { Write-Error "file.txt does not exist" }
if ($?) { Get-Content -Raw ./file.txt }
Interazione con errori
Gli operatori della catena di pipeline non assorbono gli errori. Quando un'istruzione in una catena di pipeline genera un errore di terminazione dello script, la catena di pipeline viene terminata.
Ad esempio:
$(throw 'Bad') || Write-Output '2'
Exception: Bad
Anche quando viene rilevato l'errore, la catena di pipeline viene ancora terminata:
try
{
$(throw 'Bad') || Write-Output '2'
}
catch
{
Write-Output "Caught: $_"
}
Write-Output 'Done'
Caught: Bad
Done
Se un errore non termina o termina solo una pipeline, la catena di pipeline continua, rispettando il valore di $?
:
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
Concatenamento di pipeline anziché comandi
Gli operatori della catena di pipeline, in base al nome, possono essere usati per concatenare le pipeline, anziché solo i comandi. Questo corrisponde al comportamento di altre shell, ma può rendere più difficile determinare:
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
Si noti che Write-Output 'All done!'
non viene eseguito, poiché Test-NotTwo
viene considerato non riuscito dopo la generazione dell'errore non irreversibile.
Vedi anche
Commenti e suggerimenti
https://aka.ms/ContentUserFeedback.
Presto disponibile: Nel corso del 2024 verranno gradualmente disattivati i problemi di GitHub come meccanismo di feedback per il contenuto e ciò verrà sostituito con un nuovo sistema di feedback. Per altre informazioni, vedereInvia e visualizza il feedback per