我有一个批处理文件,我通过cmd /c a.bat
从msysgit bash shell脚本运行,然后测试退出代码以确定是否继续。当批处理文件失败时,从失败的任何地方调用exit /b 1
,批处理文件以代码1退出。
我最近注意到,如果批处理文件在调用exit /b 1
的某个点失败,则不返回退出代码,而是返回0.它只发生在内部块中。这是一个例子:
@echo off
if foo EQU foo (
if bar EQU bar (
echo Exiting with code 99.
exit /b 99
)
echo this line is necessary to reproduce the issue
)
应始终退出99,但是:
X:\j\tmp>doesnotexist
'doesnotexist' is not recognized as an internal or external command,
operable program or batch file.
X:\j\tmp>echo %ERRORLEVEL%
9009
X:\j\tmp>cmd /c a.bat
Exiting with code 99.
X:\j\tmp>echo %ERRORLEVEL%
0
X:\j\tmp>cmd /c call a.bat
Exiting with code 99.
X:\j\tmp>echo %ERRORLEVEL%
99
如果删除了最后一个回显行,那么cmd /c a.bat
会返回退出代码99.正如我在实际批处理文件中提到的,exit /b <Code>
大部分时间都可以正常工作。
我可以在Windows 7和10中重现。我的问题是为什么它不会在上面的repro中返回退出代码?这是一个错误或我做错了什么?正如你所看到的,我试图预感CALL
这似乎可以解决这个问题,但我不确定为什么。 CALL
应该用于从另一个批处理而不失去控制权。
答案 0 :(得分:0)
您正在启动一个新的cmd.exe
实例,它将在新窗口而不是当前窗口中产生99错误。
使用call
运行代码时获取正确代码的原因纯粹是因为您告诉它在当前控制台中运行批处理文件,因此您获得退出代码99
因此您无需运行cmd /c
即可启动该文件。而是将批处理文件简单地运行为:
c:\path_to\file\a.bat
或者如果在路径或当前目录中:
a.bat
答案 1 :(得分:-1)
当您调用cmd / c时,您正在创建新的cmd.exe进程,并且该进程正在调用您的脚本。因此,新进程中的errorcode变量设置为99,但cmd进程成功退出,在启动命令提示符中将级别设置回0。
如果您只是运行a.bat,则会正确设置错误级别。如果您尝试使用cmd / k a.bat,则新cmd仍将运行,并且您将能够看到错误级别为99.然后,根据您退出的方式,原始cmd的错误级别将适当设置。