为什么 PowerShell 在下面的第二个示例中显示出令人惊讶的行为?
首先,一个理智行为的例子:
PS C:\> & cmd /c "echo Hello from standard error 1>&2"; echo "`$LastExitCode=$LastExitCode and `$?=$?"
Hello from standard error
$LastExitCode=0 and $?=True
没有惊喜。我向标准错误打印一条消息(使用cmd
's echo
)。我检查变量$?
和$LastExitCode
. 正如预期的那样,它们分别等于 True 和 0。
但是,如果我要求 PowerShell 通过第一个命令将标准错误重定向到标准输出,我会收到 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?
其次,为什么运行成功$?
时为 False为 0?PowerShell关于自动变量的文档没有明确定义. 我一直认为当且仅当为 0 时它为真,但我的示例与此相矛盾。cmd
$LastExitCode
$?
$LastExitCode
以下是我在现实世界中遇到这种行为的方式(简化)。这真的是FUBAR。我正在从另一个调用一个 PowerShell 脚本。内部脚本:
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
。在这种情况下,将发送一封电子邮件!您在脚本之外使用错误流执行的操作会影响脚本的内部行为。观察一个现象会改变结果。这感觉就像是量子物理学而不是脚本!
[有趣的是:.\job.ps1 2>&1
可能会或不会爆炸,具体取决于您运行它的位置]