$ LastExitCode = 0, ale $? = False w PowerShell. Przekierowanie stderr na stdout daje NativeCommandError
Dlaczego PowerShell pokazuje zaskakujące zachowanie w drugim przykładzie poniżej?
Po pierwsze, przykład zdrowego zachowania:
PS C:\> & cmd /c "echo Hello from standard error 1>&2"; echo "`$LastExitCode=$LastExitCode and `$?=$?"
Hello from standard error
$LastExitCode=0 and $?=True
Bez niespodzianek. Drukuję wiadomość do standardowego błędu (używająccmd
jestecho
). Sprawdzam zmienne$?
i$LastExitCode
. Zgodnie z oczekiwaniami są one równe odpowiednio Prawdzie i 0.
Jeśli jednak poproszę PowerShell o przekierowanie standardowego błędu na standardowe wyjście w pierwszym poleceniu, otrzymam błąd 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
Moje pierwsze pytanie, dlaczego NativeCommandError?
Po drugie, dlaczego jest$?
Fałszywe kiedycmd
uruchomione pomyślnie i$LastExitCode
jest 0? Dokumentacja PowerShello zmiennych automatycznych nie definiuje wyraźnie$?
. Zawsze przypuszczałem, że to prawda, jeśli i tylko wtedy$LastExitCode
wynosi 0, ale mój przykład temu zaprzecza.
Oto jak natknąłem się na to zachowanie w świecie rzeczywistym (uproszczonym). To naprawdę jest FUBAR. Dzwoniłem do jednego skryptu PowerShell z innego. Wewnętrzny skrypt:
cmd /c "echo Hello from standard error 1>&2"
if (! $?)
{
echo "Job failed. Sending email.."
exit 1
}
# Do something else
Bieganie po prostu jak.\job.ps1
, działa dobrze i nie jest wysyłany e-mail. Dzwoniłem jednak z innego skryptu PowerShell, logując się do pliku.\job.ps1 2>&1 > log.txt
. W takim przypadku wysyłany jest e-mail! To, co robisz poza skryptem ze strumieniem błędu, wpływa na wewnętrzne zachowanie skryptu.Obserwacja zjawiska zmienia wynik. To raczej fizyka kwantowa niż skrypty!
[Co ciekawe:.\job.ps1 2>&1
może wysadzić w powietrze lub nie, w zależności od tego, gdzie go uruchomisz]