$ 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.ps1
funktioniert, 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]