如果一个命令失败,则禁止输出块(并输出自定义错误消息)

时间:2013-03-07 03:14:08

标签: batch-file

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

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之类的东西,或者类似的东西,我想这就是要走的路。但我也猜测每次运行命令时都会抑制输出,而不仅仅是在出现错误信息时。

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

2 个答案:

答案 0 :(得分: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

通常,||之后的命令仅在先前命令失败时触发。 ||运算符通常不直接读取%ERRORLEVEL%变量,它通常直接检测先前命令的错误状态。

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

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

尝试确定哪些命令始终设置ERRORLEVEL会有点棘手,如果出现错误,哪些命令只会设置ERRORLEVEL。我相信内部命令仅在出现错误时设置ERRORLEVEL,并且如果命令成功则不清除任何先前的ERRORLEVEL。 (我假设.BAT分机。我相信.CMD分机会改变行为)

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

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

我认为只有在所有命令成功时才打印stdout的唯一方法是将所有stdout重定向到一个临时文件,并保持标签是否有任何命令失败。在块结束时,当且仅当没有错误时,您可以输入临时文件内容。然后删除临时文件。

答案 1 :(得分: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

运行它会产生

布拉赫 胡说 其中一个命令失败1。 胡说 胡说 胡说 其中一个命令失败2。

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

我同意过时的错误级别理论 - 在调用BLOCK2子例程之前将错误级别强制为0来修复问题。

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