您可以使用| more
逐步执行.bat文件,并且可以将输出重定向到文件以供以后分析,但通常错误并不明显。你没有得到一个方便的“错误:”前缀和dos命令可以打印的错误是多种多样的。这使得彻底搜索任何可能的错误非常困难。
所以我想知道在发生错误时是否有办法让批处理文件自动暂停?
答案 0 :(得分:1)
Afaik,没有通用方法,尤其是与|more
结合使用时。
但是许多命令返回errorlevel
,您可以阅读并采取行动。
以下是某些命令返回的一些错误级别的列表。例如,find
如果未找到结果则返回1,如果搜索因其他原因而中止,则返回更高的值。
所以你可以这样写:
find ...parameters...
if ERRORLEVEL 1 (
echo 'No files found'
pause
)
if ERRORLEVEL X
语法匹配任何> = X的错误级别。这很方便,因为许多程序返回0或特定的低值表示成功,更高的值表示错误,大多数命令都是列表,因此这个语法允许您在一个条件下捕获所有这些错误代码。
您必须阅读命令的文档或您在批处理文件中启动的程序,以查看它们是否返回错误级别,如果是,则返回每个值的含义。
答案 1 :(得分:1)
批处理没有任何异常处理。如果要可靠地检测错误,那么您的脚本必须在每个命令后显式检查错误情况。但这可能是一个繁琐的过程,对现有的脚本来说并不是很实用。
我无法想到在每个错误之后暂停的简单方法,但您可以检测在执行期间是否可能出现错误。您可以编写另一个批处理脚本来调用脚本,并将stderr重定向到文件。然后在完成后检查错误文件的大小 - 如果大于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)一些命令将信息文本写入stderr,这不是真正的错误。如果这是您的问题,那么您就不能使用此方法。
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
不幸的是,如果要在同一个日志文件中捕获stdout和stderr,这将无法工作。您将回到将错误文本与非错误文本区分开来的问题。
答案 2 :(得分:1)
另一种解决方案也是基于识别发送到STDERR的错误消息,因此它在答案中遇到了dbenham描述的相同问题,但它不需要以任何方式修改现有的批处理文件。 / p>
该解决方案使用this trick来显示以一种颜色开头的正常线条和以不同颜色开头的错误线条。这样,您可以区分屏幕中的错误行,但如果输出被重定向,颜色不会存储在文本文件中。
( theBatchFile | findstr /N /A:2A "^" ) 2>&1 1>&3 | findstr /N /A:4E "^"
此方法的问题在于,法线和错误线不会以原始顺序出现,而是出现在分隔部分中。发生这种情况是因为每个行块都由不同的findstr
命令处理,但在某些情况下这个解决方案可能就足够了。
编辑:添加新方法
我对这个解决方案做了几次测试。 Stdout和Stderr线路没有按照我最初的想法进行分组。它的顺序取决于启动第二个findstr
的初始延迟,这会导致初始Stderr行被延迟,以及两个输出可能在屏幕中混合的事实。如果批处理文件现在显示大部分Stdout行和几条Stderr行,则输出将保留原始顺序。
我编写了一个名为ShowErrors.bat
的小型Batch-JScript混合脚本,它允许以任何方式区分Stderr行:
@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());
}
这是一个小型批处理文件,作为混合Stdout / Stderr输出程序的示例:
@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