尝试自动执行旧程序的一些 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
条件命令。
%DATE%
与许多其他变量一样,它们是 cmd.exe 的新功能,并且需要命令扩展被启用
如果命令扩展被禁用,则以下动态变量将无法访问:
%CD% %DATE% %TIME% %RANDOM% %ERRORLEVEL% %CMDEXTVERSION% %CMDCMDLINE% %HIGHESTNUMANODENUMBER%
如果关闭命令扩展以实现 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%
答案2
您不应尝试使用%ERRORLEVEL%
,因为它比 DOS 更新,正如 @phuclv 所述。相反,使用较旧的IF ERRORLEVEL n
构造,它测试错误级别是否n 或更大。这意味着你应该测试可能的错误级别降序命令:
IF ERRORLEVEL 5 ...
IF ERRORLEVEL 4 ...
IF ERRORLEVEL 3 ...
...
您应该阅读有关检测错误级别的部分SS64 的错误级别,特别注意开头讨论与 DOS 的兼容性。