2

标题几乎总结了它,但我会详细说明我的问题。出于好奇,我一直将命令放在一个块中(通常使用一个不起作用的命令)并查看是否可以抑制错误消息并输出自定义消息。我尝试了两种方法,第一种失败但第二种有效。

1

@echo off
(
    echo Blah
    ehco Blah & rem Intentional mistake
    echo Blah
) 2>nul||echo One of the commands failed.
pause>nul

输出:

Blah
Blah

2

@echo off
call :block 2>nul||echo One of the commands failed.
pause>nul
exit
:block
(
    echo Blah
    ehco Blah & rem Intentional mistake
    echo Blah
)
goto :eof

输出:

Blah
Blah
One of the commands failed.

所以,我已经回答了问题的第二部分,现在我只需要知道如何(如果其中一个命令失败)抑制除自定义错误消息之外的任何输出。因此,所需的输出将是One of the commands failed.. 我该怎么做呢?

注意: 我听说你可以做类似echo Blah 2>&1nul或类似的事情,我想这就是要走的路。但我也猜想这会在每次运行命令时抑制输出,而不仅仅是在出现错误消息时。

另外,在您的回答中,如果您可以简要解释第一个脚本失败的原因,那将是花花公子。

4

2 回答 2

1

非常有趣的话题,但你还没有解决任何问题——你自欺欺人:-)

我运行了您的代码的细微变化,但事情不再像您期望的那样工作!

@echo off
:: clear any existing error
call;

echo %errorlevel%
(
    echo Blah
    ehco Blah & rem Intentional mistake
    echo Blah
) 2>nul||echo One of the commands failed.
echo %errorlevel%

echo(
echo --------------------------
echo(

echo %errorlevel%
call :block 2>nul||echo One of the commands failed.
echo %errorlevel%
exit /b

:block
echo Blah
echo Blah
echo Blah
exit /b

- - 输出 - -

0
Blah
Blah
9009

--------------------------

9009
Blah
Blah
Blah
One of the commands failed.
9009

通常,||只有在前面的命令失败时才会触发 after 的命令。操作者||通常不会%ERRORLEVEL%直接读取变量,它通常直接检测先前命令的错误状态。

在第一组代码中,其中一个命令失败,ERRORLEVEL 设置为 9009。但块中的最后一个命令成功,因此条件失败消息不会触发。

第二个代码块使用 CALL。执行 CALL 时,返回时的当前 %ERRORLEVEL% 通常用作 CALL 命令的返回状态。进入例程时 ERRORLEVEL 为 9009,例程中的任何命令都不能清除错误,因此返回 9009 作为 CALL 语句的错误状态。通过将错误级别指定为 EXIT /B 之后的附加参数,可以强制返回代码为任何值。例如,exit /b 0

试图找出哪些命令总是设置 ERRORLEVEL 以及哪些命令仅在出现错误时才设置 ERRORLEVEL 可能会有点棘手。我相信内部命令仅在出现错误时设置 ERRORLEVEL,如果命令成功,则不清除任何先前的 ERRORLEVEL。(我假设.BAT扩展。我相信.CMD扩展会改变行为)

大多数(全部?)外部命令总是设置 ERRORLEVEL。这取决于可执行文件,但大多数外部命令返回 0 表示成功,非 0 表示失败。

由于代码块可能包含内部和外部命令的混合,因此如果任何命令失败,您不能假设最终的 ERRORLEVEL 将非零。干预的外部命令可能已清除 ERRORLEVEL。您应该检查每个命令的返回码并设置错误变量以保留块中存在的错误。然后,您可以使用 EXIT /B 显式返回所需的错误代码。

我认为仅在所有命令成功时才打印标准输出的唯一方法是将所有标准输出重定向到一个临时文件,并密切关注是否有任何命令失败。在块结束时,当且仅当没有错误时,您才能 TYPE 临时文件内容。然后无论如何删除临时文件。

于 2013-03-07T04:18:21.880 回答
0

这是我的测试批次:

@echo OFF
call :block 2>nul||echo One of the commands failed 1.
call :block2 2>nul||echo One of the commands failed 2.
GOTO :eof

:block
(
    echo Blah
    ehco Blah & rem Intentional mistake
    echo Blah
)
goto :eof
:block2
(
    echo Blah
    echo Blah & rem Intentional mistake
    echo Blah
)
goto :eof

运行它会产生

Blah Blah 其中一个命令失败 1. Blah Blah Blah 其中一个命令失败 2.

无论是保存为 .bat 还是 .cmd

我会同意陈旧的错误级别理论——在调用 BLOCK2 子例程修复问题之前强制错误级别为 0。

因此,您获得的行为取决于现有的错误级别设置 - 您可能会得到意想不到的结果......

于 2013-03-07T05:09:48.593 回答