$ 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ąccmdjestecho). 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]

questionAnswers(4)

yourAnswerToTheQuestion