以下の 2 番目の例で、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
) 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が 0 になるのはなぜですか? 自動変数に関するPowerShell のドキュメントでは、明示的に定義されていません。が 0 の場合にのみ True であると常に想定していましたが、私の例はそれと矛盾しています。cmd
$LastExitCode
$?
$LastExitCode
これが、現実世界でこの動作に遭遇した方法です(簡略化)。まさにFUBARです。ある 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
、実行する場所によって爆発する場合としない場合があります]