2012-07-12 49 views
5

如何使Powershell的行爲像Bash的標誌set -eset -e製作一個Bash腳本「如果一個簡單的命令以非零狀態退出,立即退出」。Bash's set -e的Powershell模擬器

我以爲我可以通過設置$ErrorActionPreference="Stop"來做到這一點,但這似乎不起作用。假設我有一個劇本a.ps1

$ErrorActionPreference="Stop" 
& cmd /c "exit 1" 
echo "cmd exited `$LastExitCode=$LastExitCode and `$?=$?" 

如果我運行它

.\a. ; echo "a.ps1 exited `$LastExitCode=$LastExitCode `$?=$?" 

要我的意外,打印

cmd exited $LastExitCode=1 and $?=False 
a.ps1 exited $LastExitCode=1 $?=True 

這是怎麼回事?我期望a.ps1在第一行後退出,拋出一個錯誤並設置$?假。

是否有任何正式文件解釋$ ErrorActionPreference?我發現的所有內容都是關於咖啡的博客上的this post

回答

9

$ErrorActionPreference按預期工作,只是本機程序的退出代碼幾乎沒有PowerShell cmdlet那麼好。

對於cmdlet錯誤條件相當容易確定:是否發生異常?所以下面不會與$ErrorActionPreference設置爲Stop達到Write-Host聲明:

Write-Error blah 

Get-ChildItem somepathwhichsurelydoesntexisthere 

對於原生的程序沒有錯誤發生,但零個通常信號的退出代碼這僅僅是一個慣例,因爲非零退出代碼表示錯誤。你會說如果choice存在退出碼爲1,那是錯誤嗎?

處理此問題的唯一可靠方法是在運行本機命令並自行處理它(如果需要)後檢查退出代碼。 PowerShell不會試圖猜測結果是什麼意思,因爲在這種情況下,約定的強度不足以保證默認行爲。

function Invoke-NativeCommand { 
    $command = $args[0] 
    $arguments = $args[1..($args.Length)] 
    & $command @arguments 
    if (!$?) { 
    Write-Error "Exit code $LastExitCode while running $command $arguments" 
    } 
} 

但總的來說許多程序需要不同的處理,因爲他們堅持不說的約定:

,如果你想使您的生活更輕鬆,您可以使用的功能。

+1

傻瓜,這是令人沮喪的。感謝這個功能,我會使用它。 – 2012-07-12 13:54:30

+1

該功能很好。我將'!$?'測試改爲'$ LastExitCode -ne 0',因爲'$?'壞了http://stackoverflow.com/questions/10666101/powershell-lastexitcode-0-but-false-redirecting-stderr- to-stdout-giving-nat – 2012-07-12 14:16:45

+0

對,就是這樣。我也注意到在任何情況下,你的錯誤條件都可能需要適應;) – Joey 2012-07-12 14:54:01

相關問題