2011-06-21 62 views
3

通常,可以使用$ ErrorActionPreference來停止在發生錯誤時執行PS腳本,如下面使用無效subversion命令的示例所示。腳本在第一個命令後退出。自動停止對bat錯誤的powershell腳本

$ErrorActionPreference='Stop' 
svn foo 
svn foo 

嘗試與maven命令(mvn.bat)執行相同的操作將執行這兩個命令。

$ErrorActionPreference='Stop' 
mvn foo 
mvn foo 

最初我懷疑mvn.bat沒有設置錯誤代碼,PS只是沒有看到錯誤。但是,$?正確設置如下列證明,當PS第一個錯誤後退出:

mvn foo 
if (-not $?) {exit 1} 
mvn foo 

因此,這裏是我的問題:鑑於這兩個svn.exe和mvn.bat設定失敗的錯誤代碼,爲什麼用PS腳本不會在mvn錯誤後停止。我發現在全局設置「$ ErrorActionPreference = Stop」更方便,而不是在每個命令後面都會出現「if(-not $?){exit 1}」以終止出錯。

回答

1

並非所有的命令行程序都以相同的方式提供錯誤。一些設置退出代碼。有些不。有些使用錯誤流,有些則不使用。我看到一些命令行程序實際上輸出了所有錯誤,並且總是輸出非零的返回碼。

因此,沒有一個真正的安全猜測可以使它成功運行,因此幾乎不可能將該行爲編碼到PowerShell中。

$ errorActionPreference每當.exe寫入錯誤流時都會實際停止腳本,但許多.exes會將常規輸出寫入控制檯,並且不會填充錯誤流。

但它不會可靠地工作。對此,也不會有$ ?.如果一個exe返回0並且不寫入錯誤$?將是真實的。

雖然在PowerShell中處理這些單獨的.exes及其錯誤可能會很痛苦,但它是PowerShell高度結構化的輸出/錯誤/詳細/警告/調試/進程流以及Cmdlet中一致的錯誤行爲擊敗了普通的舊.EXE工具。

希望這有助於

+0

謝謝,它有幫助。但同時,我認爲PS dev團隊根據錯誤流上的活動來檢測失敗的決定並不是很有啓發性。從一開始,程序就會返回一個非零的退出代碼來表示錯誤。也許並不是每一個程序都這樣做,但unix shell腳本在這個約定中工作得很好。這不是關於PS有多棒,而是關於它如何與外部程序集成。 –

+0

我建議你沒有閱讀回覆。您會驚訝於不可靠的退出代碼,甚至錯誤流中的消息。 PowerShell會將非零退出代碼解釋爲失敗。 $?反映這一點。儘管如此,它不應該完全停止腳本,因爲這意味着任何單個數據的單個問題總是會停止批量操作。這會使更多的操作變得更加困難。 –

+1

我確實很仔細地閱讀了回覆。但我的觀點仍然有效。如果我將$ errorActionPreference設置爲「Stop」,那麼我希望PS能夠適應這一點。 如果您閱讀我的第一篇文章,腳本停止svn.exe(可能是因爲它也寫入錯誤流)。但是在mvn.bat的情況下,腳本不會停止(可能是因爲它不寫入錯誤流)。 –

1

$ ErrorActionPreference控制方面的命令行開關和PowerShell功能PowerShell的行爲 - 這是不是「遺產」命令退出代碼敏感。我仍然在爲自己的設計決定尋找解決方法 - 對於這個問題,請參閱此主題:How to stop a PowerShell script on the first error?。您可能會得出結論,這個定製的「執行」功能是最好的解決辦法:http://jameskovacs.com/2010/02/25/the-exec-problem/

關於停止對-標準錯誤行爲,我不能在PowerShell中3重現此問題:

Invoke-Command 
{ 
    $ErrorActionPreference='Stop' 
    cmd /c "echo hi >&2"   # Output to stderr (this does not cause termination) 
    .\DoesNotExist.exe   # Try to run a program that doesn't exist (this throws) 
    echo bye      # This never executes 
} 

更新:使用PS遠程處理時,stop-on-stderr行爲似乎生效。