$ LastExitCode = 0, aber $? = False in PowerShell. Wenn Sie stderr nach stdout umleiten, erhalten Sie NativeCommandError

Warum zeigt PowerShell das überraschende Verhalten im zweiten Beispiel unten?

Erstens ein Beispiel für gesundes Verhalten:

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

Keine Überraschungen. Ich drucke eine Nachricht auf Standardfehler (mitcmd'secho). Ich inspiziere die Variablen$? und$LastExitCode. Sie sind erwartungsgemäß gleich True und 0.

Wenn ich PowerShell jedoch auffordere, Standardfehler über den ersten Befehl an die Standardausgabe umzuleiten, erhalte ich einen 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

Meine erste Frage, warum der NativeCommandError?

Zweitens, warum ist$? Falsch wanncmd lief erfolgreich und$LastExitCode ist 0? PowerShell-Dokumentationüber automatische Variablen definiert nicht explizit$?. Ich habe immer angenommen, es ist wahr, wenn und nur wenn$LastExitCode ist 0, aber mein Beispiel widerspricht dem.

Hier ist, wie ich auf dieses Verhalten in der realen Welt gestoßen bin (vereinfacht). Es ist wirklich FUBAR. Ich habe ein PowerShell-Skript von einem anderen aufgerufen. Das innere Drehbuch:

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

Laufen diese einfach als.\job.ps1funktioniert, und es wird keine E-Mail gesendet. Ich habe es jedoch von einem anderen PowerShell-Skript aus aufgerufen und in einer Datei protokolliert.\job.ps1 2>&1 > log.txt. In diesem Fall wird eine E-Mail verschickt! Was Sie außerhalb des Skripts mit dem Fehlerstrom tun, wirkt sich auf das interne Verhalten des Skripts aus.Das Beobachten eines Phänomens verändert das Ergebnis. Das fühlt sich eher nach Quantenphysik an als nach Skripten!

[Interessant:.\job.ps1 2>&1 kann explodieren oder nicht, je nachdem, wo Sie es ausführen]

Antworten auf die Frage(4)

Ihre Antwort auf die Frage