【问题标题】:Dos prompt - pause execution/display on error only?Dos 提示 - 仅在错误时暂停执行/显示?
【发布时间】:2013-11-23 14:32:41
【问题描述】:

您可以使用| more 单步执行 .bat 文件,并且可以将输出重定向到文件以供以后分析,但通常错误并不那么明显。您没有方便的“ERROR:”前缀,并且 dos 命令可以打印的错误多种多样。这使得彻底搜索任何可能的错误变得非常困难。

所以我想知道是否有办法让批处理文件在发生错误时自动暂停?

【问题讨论】:

  • 如果您指的是语法错误,那么不,没有方便的调试器。
  • @foxidrive - 出错后我无法暂停,但我想出了一种方法来检测是否有错误(可能会出现一些误报)。看我的回答。

标签: windows batch-file cmd


【解决方案1】:

Afaik,没有通用的方法,尤其是与|more 结合使用时。 但是许多命令会返回一个errorlevel,您可以阅读并采取行动。

这里是 some 命令返回的一些错误级别的列表。例如,find 如果没有找到结果,则返回 1,如果搜索因其他原因中止,则返回更高的值。

所以你可以这样写:

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

if ERRORLEVEL X 语法匹配 >= X 的任何错误级别。这很方便,因为许多程序返回 0 或特定的低值表示成功,返回较高的值表示错误,列表中的大多数命令也是如此,因此,此语法允许您在单个条件下捕获所有这些错误代码。

您必须阅读命令或您在批处理文件中启动的程序的文档,以查看它们是否返回错误级别,如果是,每个值的含义。

【讨论】:

  • 啊,我想在 .bat 文件外部进行,即不修改现有文件。
  • 您可以使用exit /b。输入exit /? 寻求帮助。
【解决方案2】:

Batch 没有任何异常处理。如果您想可靠地检测错误,那么您的脚本必须在每个命令之后显式检查错误情况。但这可能是一个乏味的过程,而且对于现有脚本来说不是很实用。

我想不出一个简单的方法来在每个错误后暂停,但您可以检测在执行过程中的某个时间点是否可能出现错误。您可以编写另一个批处理脚本来调用您的脚本,并将 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 程序并将 stderr 与 stdout 交换,你可以解决这个问题。获取 tee 的一个免费来源是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,这将不起作用。您会遇到区分错误文本和非错误文本的问题。

【讨论】:

    【解决方案3】:

    还有另一种解决方案,它也是基于识别发送到 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 的小型 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
    

    【讨论】:

      猜你喜欢
      • 2017-03-02
      • 1970-01-01
      • 2021-04-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-09-22
      • 1970-01-01
      相关资源
      最近更新 更多