这个stackoverflow answer解释了Linux真正的命令是什么。我的问题,Powershell(v5 / v6)是否也提供了真正的命令?
我已经用Google搜索了,使用了Get-help *true*
,但找不到任何相关信息。
谢谢
简而言之:
true
和false
Unix实用程序。bash
)的工作方式非常不同,所以不需要它们。Unix实用程序true
的主要用途是在你故意想要在类似POSIX的shell(如0
)中忽略先前命令失败(通过非零退出代码发出信号)的情况下将退出代码重置为bash
,例如在条件中或与有效的abort-on-unhandled-failures选项set -e
。
true
和它的对手false
都没有产生任何输出 - 它们的唯一目的是设置退出代码。
PowerShell本身不使用退出代码(尽管您可以使用exit <n>
为外部调用者设置它们),并且其条件不会对它们起作用。
$?
变量在类似于POSIX的shell中与$?
类似,除了它报告一个布尔值,而类似POSIX的shell报告退出代码;在类似POSIX的shell中包含$?
的0
类似于在PowerShell中包含$?
的$true
。$?
起作用,但你可以在PowerShell条件中明确地使用它,因此以下两个 - 为简单而设计 - 命令是等价的:
# 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' }
虽然PowerShell具有自动$true
和$false
变量(概念上,常量),但它们是用于与输出(数据)进行比较的布尔值,而不是用于设置不可见状态信息(退出代码)的命令。
继续阅读以获取背景信息。
在类似POSIX的shell中,例如bash
,条件操作命令的退出代码,即(执行后)状态信息,而不是它们的输出。
相比之下,PowerShell条件操作命令或表达式输出,即数据,而不是状态信息。
简而言之:
两个shell都通过错误输出(stderr)。
您可以使用自动$?
变量,其行为取决于手头的命令是PowerShell本机命令还是外部程序(如Unix实用程序):
0
,$?
反映$true
,否则$false
这类似于类似POSIX的shell中的内置$?
变量,例如bash
,除了那里的$?
包含实际的退出代码;也就是说,在类似POSIX的shell中包含$?
的0
与执行外部程序后在PowerShell中包含$?
的$true
相同。
要在PowerShell中获取实际的退出代码,请使用自动$LASTEXITCODE
变量,它反映了最近执行的外部程序的退出代码(PowerShell本机命令通常不设置退出代码,但您可以在脚本中使用exit <n>
,主要用于报告退出代码到外部来电者)。$?
是$true
,如果命令没有从根本上失败并且没有写入PowerShell的错误流(例如使用Write-Error
;请注意,默认情况下外部程序的stderr输出不会写入PowerShell的错误流)。
请注意,$?
因此不一定告诉您给定命令是否认为其整体执行成功与否; $?
是$false
只是告诉你只报告了一些错误。
但是,您可以在try { ... } catch { ... }
语句中包装命令调用,这有助于您区分非终止错误和终止错误(默认情况下,只有后者触发catch
块);在PowerShell中使用$?
并不常见,因为故障通常是使用
-ErrorAction
通用参数/ $ErrorActionPreference
首选变量和/或try { ... } catch { ... }
语句。
也就是说,这些方法不能用于外部程序,其中测试$?
或$LASTEXITCODE
是检测故障的必要条件。
This GitHub discussion和this RFC draft呼吁将外部程序与PowerShell的错误处理更好地集成。
有关PowerShell错误处理的全面概述,请参阅this GitHub issue。
您正在寻找的是the about_Automatic_Variables
topic,其中描述了变量$true
和$false
。
我把它写成答案是因为我想指出一个“陷阱”我遇到了这些值:0
和1
分别等于$false
和$true
。
$false -eq 0 # => True
$false -eq $null # => False - not false-y?
$true -eq 1 # => True
$true -eq 2 # => True - appears to be truth-y
同时,字符串'false'
不是。
$false -eq 'False' # => False
此外,由于某种原因,$false
等于空字符串:
$false -eq '' # => True
$false -eq [string]::Empty # => True
虽然字符串'true'
等于$true
(实际上,任何非零数字,任何非空字符串都是):
$true -eq 'True' # => True
在写这个答案的探索中,我意识到很多$true
比较评估为True
,所以假设与bool常数的比较是真实的y / false-y是安全的。
以下是与$false
比较的值(这使得以下比较返回$true
):
$false -eq '' # Empty string
$false -eq 0 # Zero
$false -eq @() # Empty array
我发现两次测试失败的唯一比较是$null
(所以不是100%false-y):
$false -eq $null # => False
$true -eq $null # => False
在一些其他语言中评估为$false
的最后一个示例边缘情况是空[hashtable]
(或字典):
$true -eq @{} # => True
总结一下@Joey在评论中所说的:
╦═════════════════════╦═════════════════════════╗
║ 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 ║
╚═════════════════════╩═════════════════════════╝