我有一个变量为%errorlevel%
的a.bat,以及调用b.bat的以下行:
start /wait cmd /c b.bat
如果b.bat
设置%errorlevel%
(例如errorlevel = 5
)
如果不使用CALL命令,我怎样才能在%errorlevel%
中仅保留此a.bat
变量。
我不想使用CALL的原因是因为b.bat
包含一些我不想保留的变量。
答案 0 :(得分:1)
您不必公开内部变量来在脚本之间进行通信。您可以使用常规参数将值发送到被调用脚本,并从%ERRORLEVEL%
环境变量获取其数值结果。在以下示例中,a.cmd
将参数传递给b.cmd
并接收其执行结果(来自%ERRORLEVEL%
):
:: a.cmd ----
SETLOCAL
SET ARGUMENT=123
CALL b.cmd "%ARGUMENT%"
SET RESULT=%ERRORLEVEL%
ECHO B returned this numeric value as result (%RESULT%)
:: b.cmd ----
SETLOCAL
SET OTHERVAR=%~1
ECHO B received this value as argument (%OTHERVAR%)
EXIT /B 33000
我强调了避免对变量使用保留名称的建议(如@dbenham也评论过)。
答案 1 :(得分:1)
此答案自最初发布以来已经过重大编辑。
您的命令应该按照当前编写的方式工作,尽管我认为使用START没有任何优势。简单地使用它会更简单,更有效:
cmd /c "b.bat"
由b.bat设置的ERRORLEVEL应该由CMD命令返回。当然,如果您创建了一个名为ERRORLEVEL的环境变量来屏蔽Windows维护的动态值,那么这将无效。
但是,我认为修改b.bat以使其顶部有SETLOCAL
会更好(如果可能的话)。 b.bat定义的任何变量都是临时的,一旦脚本结束就会被遗忘。然后你可以使用CALL,b.bat中的变量将会消失,但ERRORLEVEL将为调用者正确设置。
<强> b.bat 强>
@echo off
setlocal
set var=This value will be "forgotten" when b.bat ends
dir "This does not exist so ERRORLEVEL will be set to 1"
<强> caller.bat 强>
@echo off
set var=
call b.bat
echo ERRORLEVEL=%errorlevel%
set var
但根据您的评论,听起来好像您在b.bat中有一行如下所示:
set errorlelvel=%errorsaved%
你永远不应该为ERRORLEVEL定义自己的值,因为它会破坏ERRORLEVEL应该用于的功能。
相反,您应该使用EXIT / B在脚本末尾设置errorlevel
@echo off
setlocal
...
set someVar=anything. This value will be gone at script end because of SETLOCAL
...
someCommandThatGeneratesAnError
set errorsaved=%errorlevel%
...
exit /b %errosaved%
如果您尝试从b.bat(而不是ERRORLEVEL)中选择性地持久保存用户定义的变量,那么您真的应该修改b.bat以使SETLOCAL
位于顶部,然后使用ENDLOCAL
与多种方法中的任何一种相结合,以在ENDLOCAL屏障上保持一个值。看看Make an environment variable survive ENDLOCAL