$LastExitCode=0, но $?=False в PowerShell. Перенаправление stderr в stdout приводит к NativeCommandError

Почему 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, если cmdвыполнен успешно и $LastExitCodeравен 0? Документация PowerShell об автоматических переменныхне определяет явно $?. Я всегда предполагал, что это True тогда и только тогда, когда $LastExitCodeравно 0, но мой пример противоречит этому.


Вот как я столкнулся с таким поведением в реальном мире (упрощенно). Это действительно ФУБАР. Я вызывал один сценарий 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может взорваться или не взорваться в зависимости от того, где вы его запустите]

43
задан Machavity 17 August 2019 в 14:00
поделиться