This stackoverflow answer explains what the Linux true command is. My question, does Powershell (v5/v6) offers also a true command?
I already googled around, used Get-help *true*
, but could not find anything about it.
Thx
This stackoverflow answer explains what the Linux true command is. My question, does Powershell (v5/v6) offers also a true command?
I already googled around, used Get-help *true*
, but could not find anything about it.
Thx
In short:
There is no PowerShell equivalent to the true
and false
Unix utilities.
Because PowerShell's conditionals and error handling work very differently than in POSIX-like shells such as bash
, there is no need for them.
The primary use of Unix utility true
is to reset the exit code to 0
in situations where you deliberately want to ignore a previous command's failure (signaled via a nonzero exit code) in POSIX-like shells such as bash
, such as in conditionals or with the abort-on-unhandled-failures option set -e
in effect.
Neither true
nor its counterpart, false
, produce any output - their sole purpose is to set an exit code.
PowerShell doesn't use exit codes natively (though you can set them for the benefit of outside callers with exit <n>
), and its conditionals do not act on them.
PowerShell's automatic $?
variable is similar in the abstract to $?
in POSIX-like shells, except that it reports a Boolean, whereas POSIX-like shells report the exit code; that is $?
containing 0
in a POSIX-like shell is akin to $?
containing $true
in PowerShell.
PowerShell never acts on $?
implicitly, but you can use it in PowerShell conditionals explicitly, so that the following two - contrived for simplicity - commands would be equivalent:
# POSIX-like shells:
# Event though the `ls` command fails `|| true` makes the overall
# command succeed.
if ls /nosuchfile || true; then echo success; fi
# PowerShell:
# `$?` would reflect `$false` after the failed `ls` command.
# `$null = $null` is a dummy command that resets `$?` to `$true`
# `$?` is then *output* for the `if` to test.
if ($(ls /nosuchfile; $null = $null; $?)) { 'success' }
While PowerShell has the automatic $true
and $false
variables (conceptually, constants), they are Boolean values used for comparison with output (data), not commands that set invisible status information (exit codes).
Read on for background information.
In POSIX-like shells such as bash
, conditionals operate on the exit codes of commands, i.e., (post-execution) status information, not their output.
By contrast, PowerShell conditionals operate on command or expression output, i.e. data, not status information.
In short:
Conditionals in POSIX-like shells act on invisible exit codes and pass success output (stdout output) through.
Conditionals in PowerShell act on success output and consume it in the process.
Both shells pass error output (stderr) through.
You can use the automatic $?
variable, whose behavior depends on whether the command at hand is a PowerShell-native one or an external program such as a Unix utility:
External programs: If the program's exit code is 0
, $?
reflects $true
, otherwise $false
This is akin to the built-in $?
variable in POSIX-like shells such as bash
, except that $?
there contains the actual exit code; that is, $?
containing 0
in a POSIX-like shell is the same as $?
containing $true
in PowerShell after execution of an external program.
$LASTEXITCODE
variable, which reflect's the exit code of the most recently executed external program (PowerShell-native commands generally do not set exit codes, though you can use exit <n>
in scripts, primarily for reporting exit codes to outside callers).PowerShell-native commands (cmdlets, functions, scripts): $?
is $true
if the command did not fail fundamentally and did not write to PowerShell's error stream (such as with Write-Error
; note that stderr output from external programs by default does not write to PowerShell's error stream).
$?
therefore does not necessarily tell you whether a given command considered its overall execution successful or not; $?
being $false
merely tells you only that some error was reported.try { ... } catch { ... }
statement, which helps you distinguish non-terminating from terminating errors (by default only the latter trigger the catch
block); Use of $?
is not common in PowerShell, because failure is typically handled with the -ErrorAction
common parameter / $ErrorActionPreference
preference variable and/or try { ... } catch { ... }
statements.
That said, these methods cannot be used on external programs, where testing $?
or $LASTEXITCODE
is a must to detect failure.
This GitHub discussion and this RFC draft call for better integration of external programs with PowerShell's error handling.
For a comprehensive overview of PowerShell's error handling, see this GitHub issue.
What you're looking for is the about_Automatic_Variables
topic where the variables $true
and $false
are described.
I wrote this out as an answer because I wanted to point out a "gotcha" I ran into dealing with these values: 0
and 1
are equal to $false
and $true
, respectively.
$false -eq 0 # => True
$false -eq $null # => False - not false-y?
$true -eq 1 # => True
$true -eq 2 # => True - appears to be truth-y
Meanwhile, the string 'false'
is not.
$false -eq 'False' # => False
Also, for some reason, $false
is equal to an empty string:
$false -eq '' # => True
$false -eq [string]::Empty # => True
While the string 'true'
IS equal to $true
(indeed, any non-zero number, and any non-empty string is):
$true -eq 'True' # => True
In the exploration of writing this answer, I realized a lot of $true
comparisons evaluate to True
, so it's safe to assume comparisons to the bool constants are truth-y/false-y.
Here are the values that compare to $false
(which makes the following comparisons return $true
):
$false -eq '' # Empty string
$false -eq 0 # Zero
$false -eq @() # Empty array
The only comparison I found that failed a test to both is $null
(so not 100% false-y):
$false -eq $null # => False
$true -eq $null # => False
One last example edge-case that evaluates to $false
in some other languages is an empty [hashtable]
(or dictionary):
$true -eq @{} # => True
To sum up what @Joey stated in the comments:
╦═════════════════════╦═════════════════════════╗
║ Falsy ║ Truthy ║
╠═════════════════════╬═════════════════════════╣
║ 0 ║ Non-0 ║
║ @() ║ @(1) ║
║ @(0) ║ @(0, 1) ║
║ [string]::Empty ║ Non-empty string ║
║ $false ║ $true ║
║ 0-backed enum value ║ Any non-0 enum value ║
║ $null ║ Any non-$null reference ║
╚═════════════════════╩═════════════════════════╝