(set -e
bashのように)実行するコマンドのいずれかが失敗したときにPowerShellスクリプトを停止します。Powershellコマンド(New-Object System.Net.WebClient
)とプログラム(.\setup.exe
)の両方を使用しています。
(set -e
bashのように)実行するコマンドのいずれかが失敗したときにPowerShellスクリプトを停止します。Powershellコマンド(New-Object System.Net.WebClient
)とプログラム(.\setup.exe
)の両方を使用しています。
回答:
$ErrorActionPreference = "Stop"
方法の一部を取得します(つまり、これはコマンドレットに最適です)。
ただし、EXEの場合は$LastExitCode
、exeを呼び出すたびに自分自身をチェックして、失敗したかどうかを判断する必要があります。残念ながら、Windowsでは、EXEは「成功」または「失敗」の終了コードを構成するものに関して非常に一貫性がないため、PowerShellがここでは役に立たないと思います。ほとんどの場合、UNIX標準の0に準拠していますが、すべてが成功しているわけではありません。このブログ投稿でCheckLastExitCode関数を確認してください。あなたはそれが役に立つかもしれません。
throw "$exe failed with exit code $LastExitCode"
、$ exeは、 EXE。
悲しいことに、New-RegKeyやClear-Diskなどのバグの多いコマンドレットが原因で、これらの答えはどれも十分ではありません。私は現在、私の健全性を維持するために、すべてのpowershellスクリプトの上部にある次の行に落ち着いています。
Set-StrictMode -Version Latest
$ErrorActionPreference = "Stop"
$PSDefaultParameterValues['*:ErrorAction']='Stop'
そしてネイティブ呼び出しはこの扱いを受けます:
native_call.exe
$native_call_success = $?
if (-not $native_call_success)
{
throw 'error making native call'
}
そのネイティブコールパターンは徐々に一般的になりつつあり、より簡潔にするためのオプションを検討する必要があります。私はまだPowerShell初心者なので、提案は大歓迎です。
powershell関数とexeの呼び出しには少し異なるエラー処理が必要であり、スクリプトの呼び出し元にスクリプトが失敗したことを伝える必要があります。上に構築Exec
ライブラリPsake、すべてのエラーで停止します以下の構造を有しており、ほとんどのスクリプトのための基本テンプレートとして使用可能であるスクリプトから。
Set-StrictMode -Version latest
$ErrorActionPreference = "Stop"
# Taken from psake https://github.com/psake/psake
<#
.SYNOPSIS
This is a helper function that runs a scriptblock and checks the PS variable $lastexitcode
to see if an error occcured. If an error is detected then an exception is thrown.
This function allows you to run command-line programs without having to
explicitly check the $lastexitcode variable.
.EXAMPLE
exec { svn info $repository_trunk } "Error executing SVN. Please verify SVN command-line client is installed"
#>
function Exec
{
[CmdletBinding()]
param(
[Parameter(Position=0,Mandatory=1)][scriptblock]$cmd,
[Parameter(Position=1,Mandatory=0)][string]$errorMessage = ("Error executing command {0}" -f $cmd)
)
& $cmd
if ($lastexitcode -ne 0) {
throw ("Exec: " + $errorMessage)
}
}
Try {
# Put all your stuff inside here!
# powershell functions called as normal and try..catch reports errors
New-Object System.Net.WebClient
# call exe's and check their exit code using Exec
Exec { setup.exe }
} Catch {
# tell the caller it has all gone wrong
$host.SetShouldExit(-1)
throw
}
Exec { sqlite3.exe -bail some.db "$SQL" }
、-bail
コマンドレットパラメータとしてそれを解釈しようとしているので、エラーの原因は?引用符で囲むのはうまくいかないようです。何か案は?
function Invoke-Call {
param (
[scriptblock]$ScriptBlock,
[string]$ErrorAction = $ErrorActionPreference
)
& @ScriptBlock
if (($lastexitcode -ne 0) -and $ErrorAction -eq "Stop") {
exit $lastexitcode
}
}
Invoke-Call -ScriptBlock { dotnet build . } -ErrorAction Stop
ここでの主な違いは次のとおりです。
Invoke-Command
)-ErrorAction
組み込みコマンドレットの動作を模倣しますInvoke-Call { dotnet build $something }
& @ScriptBlock
そして、& $ScriptBlock
同じことを行うように見えます。この場合の違いをグーグルできませんでした
にリダイレクトstderr
するstdout
と、他のコマンド/ scriptblockラッパーなしでトリックが実行されるようですが、そのように動作する理由についての説明はありません。
# test.ps1
$ErrorActionPreference = "Stop"
aws s3 ls s3://xxx
echo "==> pass"
aws s3 ls s3://xxx 2>&1
echo "shouldn't be here"
これは期待どおり次を出力します(コマンドaws s3 ...
はを返します$LASTEXITCODE = 255
)
PS> .\test.ps1
An error occurred (AccessDenied) when calling the ListObjectsV2 operation: Access Denied
==> pass
$ErrorActionPreference = "Stop"
行儀プログラムのワーク(成功時にそのリターン0)?