2013-11-22 25 views
2

您可以使用| more來遍歷.bat文件,並且可以將輸出重定向到文件以供日後分析,但通常這些錯誤不是那麼明顯。您沒有得到方便的「ERROR:」前綴,dos命令可以打印的錯誤非常多樣。這使得徹底搜索任何可能的錯誤相當困難。Dos提示 - 僅在出錯時暫停執行/顯示?

所以我想知道是否有辦法讓一個批處理文件在發生錯誤時自動暫停?

+0

如果你指的是語法錯誤則沒有,有沒有方便的調試器。 – foxidrive

+1

@foxidrive - 錯誤後我無法停頓,但我想出了一種方法來檢測是否有錯誤(可能存在一些誤報)。看到我的答案。 – dbenham

回答

1

批處理沒有任何異常處理。如果您想要可靠地檢測錯誤,那麼腳本必須在每個命令之後明確檢查錯誤情況。但這可能是一個乏味的過程,對於現有的腳本來說並不實用。

我想不出在每次錯誤後暫停的簡單方法,但是您可以檢測執行過程中某個點是否有錯誤。您可以編寫另一批腳本來調用您的腳本,並將stderr重定向到一個文件。然後在完成時檢查err文件的大小 - 如果大於0,則可能有錯誤。

@echo off 
call yourScript.bat 2>err.log 
for %%F in (err.log) do if %%~zF neq 0 echo There probably was an error. 

上面有兩個問題。

1)一些命令將信息文本寫入標準錯誤,這不是真正的錯誤。如果這是你的情況的問題,那麼你不能使用這種方法。

2)錯誤不會顯示在屏幕上,並且文件中捕獲的錯誤缺少輸出其餘部分的上下文。如果您下載tee程序並使用stdout交換stderr,則可以解決此問題。獲得T恤的一個免費來源是Gnu CoreUtils for Windows

@echo off 
call test2.bat 3>&2 2>&1 1>&3|tee err.log 
for %%F in (err.log) do if %%~zF neq 0 echo Warning: There probably was an error 

不幸的是,如果你想捕捉到相同的日誌文件,標準輸出和標準錯誤這可不行。你會回來與區分錯誤文本和非錯誤文本的問題。

1

Afaik,沒有通用的方法,特別是當與|more合併時。 但許多命令返回errorlevel,您可以閱讀並採取行動。

以下是某些命令返回的一些錯誤級別的列表。例如,如果找不到結果,則find返回1,如果搜索因其他原因而中止,則返回更高值。

所以,你可以這樣寫:

find ...parameters... 
if ERRORLEVEL 1 (
    echo 'No files found' 
    pause 
) 

if ERRORLEVEL X語法的錯誤級別是匹配> = X.也就是說方便,因爲很多程序返回0或特定的低數值來表示成功和更高的值,以指示錯誤,就像列表中的大部分命令一樣,所以這個syntaxt允許你在單一條件下捕獲所有這些錯誤代碼。

您必須閱讀命令或批處理文件中啓動的程序的文檔,以確定它們是否返回錯誤級別,如果是,每個值的含義是什麼。

+0

嗯,我想在.bat文件外面做,即不修改現有的文件。 –

+0

你可以使用'exit/b'。輸入'exit/?'獲取幫助。 –

1

還有另一種解決方案也是基於識別發送給STDERR的錯誤消息,因此它有與dbenham在他的回答中描述的相同的問題,但它不需要以任何方式修改現有的批處理文件。

該解決方案使用this trick顯示以一種顏色數字開頭的法線和以不同顏色開頭的錯誤行。這樣,您可以區分屏幕中的錯誤行,但如果輸出被重定向,則顏色不會存儲在文本文件中。

(theBatchFile | findstr /N /A:2A "^") 2>&1 1>&3 | findstr /N /A:4E "^" 

這種方法的問題是,正常和誤差線未出現在其原始順序,但是在分離的部分。發生這種情況的原因是每個塊都由不同的findstr命令處理,但在某些情況下,此解決方案可能已足夠。

編輯新方法添加

我對這個解決方案提出了一些測試。起初,Stdout和Stderr行不會分組。它的順序取決於開始第二個findstr的初始延遲,這會導致初始Stderr行被延遲,並且兩個輸出可能會混合在屏幕中。如果批處理文件現在顯示大部分Stdout行和幾條Stderr行,則輸出將保留原始順序。

我編寫了一個名爲ShowErrors.bat小批量的JScript混合腳本,允許區分標準錯誤行以任何方式,你希望:

@if (@CodeSection == @Batch) @then 

@echo off 

if "%~1" equ "" (
    echo ShowErrors.bat command parameters ... 
    echo/ 
    echo Execute the command and differentiate lines sent to Stderr 
    goto :EOF 
) 

%* 2>&1 1>&3 | CScript //nologo //E:JScript "%~F0" 

goto :EOF 

@end 

while (! WScript.Stdin.AtEndOfStream) { 
    WScript.Stdout.WriteLine("======================================================"); 
    WScript.Stdout.WriteLine("ERROR: "+WScript.Stdin.ReadLine()); 
} 

這是一個小的批處理文件爲例混合標準輸出/標準錯誤輸出方案:

@echo off 
rem Initial delay 
ping -n 2 localhost > NUL 
for /L %%i in (1,1,4) do echo Starting lines to Stdout 
for %%a in ("2 4" "3 6" "4 8") do (
    for /F "tokens=1,2" %%i in (%%a) do (
     echo %%i lines to Stderr: >&2 
     for /L %%x in (1,1,%%i) do echo Line %%x to Stderr >&2 
     ping -n 1 localhost > NUL 
     echo %%j lines to Stdout: 
     ping -n 1 localhost > NUL 
     for /L %%x in (1,1,%%j) do echo Line %%x to Stdout 
    ) 
) 

這是當它以正常的方式執行輸出:test

Starting lines to Stdout 
Starting lines to Stdout 
Starting lines to Stdout 
Starting lines to Stdout 
2 lines to Stderr: 
Line 1 to Stderr 
Line 2 to Stderr 
4 lines to Stdout: 
Line 1 to Stdout 
Line 2 to Stdout 
Line 3 to Stdout 
Line 4 to Stdout 
3 lines to Stderr: 
Line 1 to Stderr 
Line 2 to Stderr 
Line 3 to Stderr 
6 lines to Stdout: 
Line 1 to Stdout 
Line 2 to Stdout 
Line 3 to Stdout 
Line 4 to Stdout 
Line 5 to Stdout 
Line 6 to Stdout 
4 lines to Stderr: 
Line 1 to Stderr 
Line 2 to Stderr 
Line 3 to Stderr 
Line 4 to Stderr 
8 lines to Stdout: 
Line 1 to Stdout 
Line 2 to Stdout 
Line 3 to Stdout 
Line 4 to Stdout 
Line 5 to Stdout 
Line 6 to Stdout 
Line 7 to Stdout 
Line 8 to Stdout 

這是當它通過ShowErrors test執行輸出:

Starting lines to Stdout 
Starting lines to Stdout 
Starting lines to Stdout 
Starting lines to Stdout 
====================================================== 
ERROR: 2 lines to Stderr: 
====================================================== 
ERROR: Line 1 to Stderr 
====================================================== 
ERROR: Line 2 to Stderr 
4 lines to Stdout: 
Line 1 to Stdout 
Line 2 to Stdout 
Line 3 to Stdout 
Line 4 to Stdout 
====================================================== 
ERROR: 3 lines to Stderr: 
====================================================== 
ERROR: Line 1 to Stderr 
====================================================== 
ERROR: Line 2 to Stderr 
====================================================== 
ERROR: Line 3 to Stderr 
6 lines to Stdout: 
Line 1 to Stdout 
Line 2 to Stdout 
Line 3 to Stdout 
Line 4 to Stdout 
Line 5 to Stdout 
Line 6 to Stdout 
====================================================== 
ERROR: 4 lines to Stderr: 
====================================================== 
ERROR: Line 1 to Stderr 
====================================================== 
ERROR: Line 2 to Stderr 
====================================================== 
ERROR: Line 3 to Stderr 
====================================================== 
ERROR: Line 4 to Stderr 
8 lines to Stdout: 
Line 1 to Stdout 
Line 2 to Stdout 
Line 3 to Stdout 
Line 4 to Stdout 
Line 5 to Stdout 
Line 6 to Stdout 
Line 7 to Stdout 
Line 8 to Stdout