web-dev-qa-db-ja.com

-コマンドの終了コードはスクリプトの終了コードと同じではありません

PowerShell -Command "&scriptname"を使用してスクリプトを実行する必要があります。PowerShellから返された終了コードが、スクリプト自体から返された終了コードと同じである場合は、本当に必要です。残念ながら、スクリプトが0を返す場合、PowerShellは0を返し、以下に示すように、スクリプトがゼロ以外の値を返す場合は1を返します。

PS C:\test> cat foo.ps1
exit 42
PS C:\test> ./foo.ps1
PS C:\test> echo $lastexitcode
42
PS C:\test> powershell -Command "exit 42"
PS C:\test> echo $lastexitcode
42
PS C:\test> powershell -Command "& ./foo.ps1"
PS C:\test> echo $lastexitcode
1
PS C:\test>

[Environment] :: Exit(42)を使用すると、ほとんど機能します。

PS C:\test> cat .\baz.ps1
[Environment]::Exit(42)
PS C:\test> powershell -Command "& ./baz.ps1"
PS C:\test> echo $lastexitcode
42
PS C:\test>

スクリプトがインタラクティブに実行される場合を除いて、シェル全体を終了します。助言がありますか?

27
ediven

スクリプトとして-Commandに送信している部分を見ると、機能しないことがわかります。 foo.ps1スクリプトを実行するスクリプトにはexitの呼び出しがないため、終了コードを返しません。

終了コードを返せば、あなたが望むことをするでしょう。また、"から'に変更します。そうしないと、PowerShellから実行する場合、2番目のPowerShellに文字列を「送信」する前に$lastexitcodeが解決されます。

PS C:\test> powershell -Command './foo.ps1; exit $LASTEXITCODE'
PS C:\test> echo $lastexitcode
42

PS:スクリプトを実行したいだけなら、-Fileパラメーターもチェックしてください。ただし、return 1のように終了エラーが発生した場合は、-Commandではないことも知っておいてください。最後のトピックの詳細については、 here を参照してください。

PS C:\test> powershell -File './foo.ps1'
PS C:\test> echo $lastexitcode
42
31
Lars Truijens

警告:PowerShellスクリプトが65535を超える終了コードを返す場合、ロールオーバーします。

$exitCode = 65536
Exit $exitCode

次のCMDが上記のこのPS1スクリプトを呼び出すと、の%errorlevel%を取得します

Powershell.exe "& 'MyPowershellScript.ps1' "; exit $LASTEXITCODE
SET ERR=%ERRORLEVEL%

終了コード65537の場合、%errorlevel%が1などになります。

一方、CMDが別のCMDを呼び出し、子スクリプトが65535を超えるエラーレベルを返す場合、問題なく通過します。

Cmd /c exit 86666

CMDは、期待どおり86666の%errorlevel%を返します。

これらすべてに注意:今、これは明確な理由なしにオンとオフになっています。

4
Mr. Annoyed

スクリプトをどのようにインタラクティブに呼び出すのですか?

私はこれを試しましたが、うまくいくようですが、PowerShellではなくDOSプロンプトから呼び出します

C:\Temp>type foo.ps1
exit 42


C:\Temp>powershell -noprofile -nologo -noninteractive -executionpolicy Bypass -file .\foo.ps1

C:\Temp>echo %errorlevel%
42

c:\Temp>
1