$ LastExitCode = 0,但在PowerShell中$?= False。将stderr重定向到stdout会给出NativeCommandError [英] $LastExitCode=0, but $?=False in PowerShell. Redirecting stderr to stdout gives NativeCommandError

查看:75
本文介绍了$ LastExitCode = 0,但在PowerShell中$?= False。将stderr重定向到stdout会给出NativeCommandError的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

PowerShell为什么在下面的第二个示例中显示出令人惊讶的行为?

Why does PowerShell show the surprising behaviour in the second example below?

首先,一个举止正常的示例:

First, an example of sane behaviour:

PS C:\> & cmd /c "echo Hello from standard error 1>&2"; echo "`$LastExitCode=$LastExitCode and `$?=$?"
Hello from standard error
$LastExitCode=0 and $?=True

没什么好奇怪的我将消息打印为标准错误(使用 cmd echo )。我检查变量 $? $ LastExitCode 。正如预期的那样,它们分别等于True和0。

No surprises. I print a message to standard error (using cmd's echo). I inspect the variables $? and $LastExitCode. They equal to True and 0 respectively, as expected.

但是,如果我要求PowerShell通过第一个命令将标准错误重定向到标准输出,则会收到NativeCommandError:

However, if I ask PowerShell to redirect standard error to standard output over the first command, I get a NativeCommandError:

PS C:\> & cmd /c "echo Hello from standard error 1>&2" 2>&1; echo "`$LastExitCode=$LastExitCode and `$?=$?"
cmd.exe : Hello from standard error
At line:1 char:4
+ cmd <<<<  /c "echo Hello from standard error 1>&2" 2>&1; echo "`$LastExitCode=$LastExitCode and `$?=$?"
    + CategoryInfo          : NotSpecified: (Hello from standard error :String) [], RemoteException
    + FullyQualifiedErrorId : NativeCommandError

$LastExitCode=0 and $?=False

我的第一个问题,为什么要使用NativeCommandError?

My first question, why the NativeCommandError?

第二,当 cmd 成功运行并且 $ LastExitCode $是错误的?为假>是0? PowerShell的文档关于自动变量没有明确定义 $?。我一直认为,当且仅当 $ LastExitCode 为0时,它才为True,但我的示例与此矛盾。

Secondly, why is $? False when cmd ran successfully and $LastExitCode is 0? PowerShell's documentation about automatic variables doesn't explicitly define $?. I always supposed it is True if and only if $LastExitCode is 0, but my example contradicts that.

这是我在现实世界中遇到此行为的方式(简体)。真的是FUBAR。我从另一个调用一个PowerShell脚本。内部脚本:

Here's how I came across this behaviour in the real-world (simplified). It really is FUBAR. I was calling one PowerShell script from another. The inner script:

cmd /c "echo Hello from standard error 1>&2"
if (! $?)
{
    echo "Job failed. Sending email.."
    exit 1
}
# Do something else

.\job.ps1 的形式运行它,效果很好,没有电子邮件已发送。但是,我是从另一个PowerShell脚本调用的,并记录到文件 .\job.ps1 2>& 1>中。 log.txt 。在这种情况下,将发送电子邮件!您在脚本外部执行的错误流会影响脚本的内部行为。 观察现象会改变结果。感觉就像量子物理学而不是脚本!

Running this simply as .\job.ps1, it works fine, and no email is sent. However, I was calling it from another PowerShell script, logging to a file .\job.ps1 2>&1 > log.txt. In this case, an email is sent! What you do outside the script with the error stream affects the internal behaviour of the script. Observing a phenomenon changes the outcome. This feels like quantum physics rather than scripting!

[有趣的是: 。\ job.ps1 2>& 1 可能会爆炸,也可能不会爆炸,具体取决于您在何处运行]

[Interestingly: .\job.ps1 2>&1 may or not blow up depending on where you run it]

推荐答案

此错误是PowerShell针对错误处理的说明性设计的不可预见的结果,因此很可能永远无法修复。如果您的脚本仅与其他PowerShell脚本一起播放,那么您是安全的。但是,如果您的脚本与来自世界各地的应用程序进行交互,则可能会咬住该错误。

This bug is an unforeseen consequence of PowerShell's prescriptive design for error handling, so most likely it will never be fixed. If your script plays only with other PowerShell scripts, you're safe. However if your script interacts with applications from the big wide world, this bug may bite.

PS> nslookup microsoft.com 2>&1 ; echo $?

False

陷阱!尽管如此,经过一些痛苦的尝试之后,您永远都不会忘记这一课。

Gotcha! Still, after some painful scratching, you'll never forget the lesson.

这篇关于$ LastExitCode = 0,但在PowerShell中$?= False。将stderr重定向到stdout会给出NativeCommandError的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆