很长一段时间后,我从bash回到powershell,我发现where对象行为非常令人困惑。
为什么以下代码段返回成功?什么也没找到!为什么这不像 grep 那样返回失败?
C:> Get-Process | ?{$_.name -like "laksdjfajsdfkjasdkf"}
C:> echo $?
True
tl;博士
# Run the command and, in addition to outputting to the console,
# collect the results in variable $result, via common parameter -OutVariable / -ov
# If you do NOT need to output to the console, simply use:
# $result = Get-Process | ...
Get-Process | ? { $_.name -like "laksdjfajsdfkjasdkf" } -ov result
# Test if the result is empty (using implicit Boolean conversion)
if (-not $result) { Write-Warning "Nothing matched." }
正如PetSerAl指出的那样,PowerShell中的PowerShell自动(布尔)$?
变量与传统shell中的退出代码不同(抽象)。
$?
只是告诉你最后一个语句是否成功,以及围绕它的规则很复杂,正如 Owain Esau 链接到的 GitHub 讨论所显示的那样。
成功意味着未发生任何错误,根据该定义,不返回任何内容的筛选操作是成功的。
简而言之:$?
在PowerShell中的用处有限。
但是,最近执行的外部程序的退出代码反映在自动变量$LASTEXITCODE
中,因此如果您实际调用了grep
,其退出代码将反映在那里。
(虽然$?
是在执行外部程序后立即设置的,以反映退出代码是否0
$True
,否则$False
,$?
在语句完成时可能已经反映了其他内容,具体取决于语句的细节,例如将调用括在(...)
中)
在本例中,你希望确定通过调用Where-Object
cmdlet(通过其内置别名?
调用)执行的筛选操作是否返回任何匹配项,但在PowerShell 中,该状态不会单独反映在任何地方。
因此,您必须检查输出本身以确定是否有任何匹配的内容,如顶部的代码段所示。
此方案中没有错误,但为了完整起见:PowerShell的错误处理很复杂,但很复杂,与传统shell不同;您可以在此处找到概述。