%ERRORLEVEL%

%ERRORLEVEL%

尝试自动执行旧程序的一些 DOSBox 脚本,我想通常使用退出代码来errorlevel控制程序流。

输入在hello_db.bat文件中给出:

@echo off
set msg=Hello
echo %msg%
dir
echo errorlevel = %errorlevel%

然后使用 调用 DOSBox dosbox hello_db.bat

输出为:

Hello
{Listing from dir}
errorlevel = 

因此,%errorlevel%扩展为一个空字符串而不是命令的退出代码dir,而第一个msg变量可以正确扩展。

我怎样才能让 DOSBoxerrorlevel在脚本中正确扩展?

根据@phuclv 的回答简短回答:

要求是在命令后插入一个暂停(如果不 OK,errorlevel != 0),所以最终这样做:

set errorany=0
:: Command is inserted here...
if errorlevel 1 set errorany=1

:: Make pause if not OK
if %errorany%==1 pause

答案1

因为%ERRORLEVEL%不是 MS-DOS 中的变量。它是 DR-DOS 和 cmd 特定的。它们完全不同

%ERRORLEVEL%

在 DR-DOS 7.02 及更高版本的 COMMAND.COM 中,此伪变量返回外部程序或命令返回的最后一个错误级别RETURN,例如“0”..”255”。另请参阅 Windows 下同名的伪变量%ERRORLEVEL%IF ERRORLEVEL条件命令。

https://en.wikipedia.org/wiki/Environment_variable#DOS

%DATE%与许多其他变量一样,它们是 cmd.exe 的新功能,并且需要命令扩展被启用

如果命令扩展被禁用,则以下动态变量将无法访问:

%CD% %DATE% %TIME% %RANDOM% %ERRORLEVEL% %CMDEXTVERSION% %CMDCMDLINE% %HIGHESTNUMANODENUMBER%

https://ss64.com/nt/syntax-variables.html

如果关闭命令扩展以实现 DOS 兼容性,您将无法访问 Windows cmd.exe 上的这些变量


如果你必须坚持使用 MS-DOS 及其 command.com,那么获取错误级别的唯一方法是使用if errorlevel降序排列

...
if errorlevel 4 set errorlvl=4
if errorlevel 3 set errorlvl=3
if errorlevel 2 set errorlvl=2
if errorlevel 1 set errorlvl=1

幸运的是,如果你真的必须处理所有 255 个错误代码,那么你实际上不必编写 255 行代码。但它仍然很长,所以如果你感兴趣的话,请参阅下面的[ § ]

如果你可以安装替代外壳(通过在 config.sys 中设置SHELL=\path\to\shell.com)然后有一些第三方shell带有错误级别变量。例如著名的 4DOS%_?

大多数内部 4DOS 命令设置错误级别值。4DOS 具有用于外部程序退出代码 ( %?)、外部程序终止原因 ( %??)、退出代码最后一个内部命令 ( %_?) 和最后一个 DOS 错误 ( %_SYSERR) 的内部变量。由于 4DOS 能够确定等于、小于、小于或等于、大于、大于或等于、不等于另一个值的值,因此很容易捕获特定错误:

IF "%_?" NE "" GOSUB ERR_HANDLER
:ERR_HANDLER
IF %_? == 1 ...
IF %_? == 2 ...
...
RETURN

ON ERROR...命令还可用于捕获(并恢复)错误。


§如何检查每个可能的错误级别:

@ECHO OFF
REM Reset variables
FOR %%A IN (1 10 100) DO SET ERR%%A=

REM Check error level hundredfolds
FOR %%A IN (0 1 2) DO IF ERRORLEVEL %%A00 SET ERR100=%%A
IF %ERR100%==2 GOTO 200
IF %ERR100%==0 IF NOT "%1"=="/0" SET ERR100=

REM Check error level tenfolds
FOR %%A IN (0 1 2 3 4 5 6 7 8 9) DO IF ERRORLEVEL %ERR100%%%A0 SET ERR10=%%A
IF "%ERR100%"=="" IF %ERR10%==0 SET ERR10=

:1
REM Check error level units
FOR %%A IN (0 1 2 3 4 5) DO IF ERRORLEVEL %ERR100%%ERR10%%%A SET ERR1=%%A
REM Modification necessary for errorlevels 250+
IF NOT ERRORLEVEL 250 FOR %%A IN (6 7 8 9) DO IF ERRORLEVEL %ERR100%%ERR10%%%A SET ERR1=%%A
GOTO End

:200
REM In case of error levels over 200 both
REM tenfolds and units are limited to 5
REM since the highest DOS error level is 255
FOR %%A IN (0 1 2 3 4 5) DO IF ERRORLEVEL 2%%A0 SET ERR10=%%A
IF ERR10==5 FOR %%A IN (0 1 2 3 4 5) DO IF ERRORLEVEL 25%%A SET ERR1=%%A
IF NOT ERR10==5 GOTO 1

:End
REM Clean up the mess and show results
SET ERRORLEV=%ERR100%%ERR10%%ERR1%
FOR %%A IN (1 10 100) DO SET ERR%%A=
ECHO ERRORLEVEL  %ERRORLEV%

信用:https://www.robvanderwoude.com/errorlevel.php

答案2

您不应尝试使用%ERRORLEVEL%,因为它比 DOS 更新,正如 @phuclv 所述。相反,使用较旧的IF ERRORLEVEL n构造,它测试错误级别是否n 或更大。这意味着你应该测试可能的错误级别降序命令:

IF ERRORLEVEL 5 ...  
IF ERRORLEVEL 4 ...  
IF ERRORLEVEL 3 ...
...

您应该阅读有关检测错误级别的部分SS64 的错误级别,特别注意开头讨论与 DOS 的兼容性。

相关内容