PowerShell [Core] 7.0 introduced Bash-like &&
and ||
operators called pipeline-chain operators.
They will not be back-ported to Windows PowerShell, however, as the latter will generally see no new features.
In short, instead of:
do-cmd-one; if ($?) { do-cmd-two }
Note: As of PowerShell 7.1, the more robust formulation is actually
do-cmd-one; if ($LASTEXITCODE -eq 0) { do-cmd-two }
, for the reasons explained in this answer.
you can now write:
do-cmd-one && do-cmd-two
&&
(AND) and ||
(OR) implicitly operate on each command's implied success status, as reflected in automatic Boolean variable $?
.
This will likely be more useful with external programs, whose exit codes unambiguously imply whether $?
is $true
(exit code 0
) or $false
(any nonzero exit code).
By contrast, for PowerShell commands (cmdlets) $?
just reflects whether the command failed as a whole (a statement-terminating error occurred) or whether at least one non-terminating error was reported; the latter doesn't necessarily indicate overall failure.
However, there are plans to allow PowerShell commands to set $?
directly, as a deliberate overall-success indicator.
Also note that the following do not work with &&
and ||
:
PowerShell's Test-*
cmdlets, because they signal the test result by outputting a Boolean rather than by setting $?
; e.g.,
Test-Path $somePath || Write-Warning "File missing"
wouldn't work.
Boolean expressions, for the same reason; e.g.,
$files.Count -gt 0 || write-warning 'No files found'
wouldn't work.
See this answer for background information, and the discussion in this GitHub issue.
There's a syntax caveat: As of this writing, the following will not work:
do-cmd-one || exit 1 # !! Currently does NOT work
Instead, you're forced to wrap exit
/ return
/ throw
statements in $(...)
, the so-called subexpression operator:
do-cmd-one || $(exit 1) # Note the need for $(...)
This GitHub issue discusses the reasons for this awkward requirement, which are rooted in the fundamentals of PowerShell's grammar.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…