Reputation: 354
I have a.bat which has a variable %errorlevel%
, and the following line which calls b.bat:
start /wait cmd /c b.bat
If b.bat
sets the %errorlevel%
(e.g. errorlevel = 5
)
How is it possible for me to persist only this %errorlevel%
variable in a.bat
, without using the CALL command.
The reason I don't want to use CALL is because b.bat
contains some variables that I do not want to persist.
Upvotes: 0
Views: 511
Reputation: 130849
This answer has been edited significantly since it was originally posted.
Your command should work as currently written, although I don't see any advantage to using START. It would be much simpler and more efficient to simply use:
cmd /c "b.bat"
The ERRORLEVEL that was set by b.bat should be returned by the CMD command. Of course this will not work if you created your own environment variable named ERRORLEVEL that masks the dynamic value maintained by Windows.
However, I think it would be better, (if possible), to modify b.bat so that it has SETLOCAL
at the top. Any variables defined by b.bat are temporary and forgotten once the script ends. Then you can use CALL and the variables in b.bat will be gone, but the ERRORLEVEL will be set properly for the caller.
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
But based on your comment, it sounds as though you have a line in b.bat like the following:
set errorlelvel=%errorsaved%
You should never define your own value for ERRORLEVEL like that because it breaks the functionality of what ERRORLEVEL is supposed to be used for.
Instead you should use EXIT /B to set the errorlevel at the end of the script
@echo off
setlocal
...
set someVar=anything. This value will be gone at script end because of SETLOCAL
...
someCommandThatGeneratesAnError
set errorsaved=%errorlevel%
...
exit /b %errosaved%
If you are trying to selectively persist a user defined variable from b.bat (not ERRORLEVEL), then you really should modify b.bat to have SETLOCAL
at the top, and then use ENDLOCAL
coupled with any one of a number of methods to persist a value across the ENDLOCAL barrier. Have a look at the top 3 voted answers to Make an environment variable survive ENDLOCAL
Upvotes: 1
Reputation: 6703
You don't have to expose inner variables to communicate between scripts. You can use regular arguments to send values to the called script and get its numeric result from %ERRORLEVEL%
environment variable. In the following sample, a.cmd
passes an argument to b.cmd
and receive the result of its execution (from %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
I reinforce the suggestion to avoid using reserved names for variables (as @dbenham also commented).
Upvotes: 1