0

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.

adarshr
  • 61,315
  • 23
  • 138
  • 167
MajorInc
  • 342
  • 3
  • 12

2 Answers2

1

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).

Gerardo Lima
  • 6,467
  • 3
  • 31
  • 47
  • Hi, thanks for the reply. what I actually want is to change %OTHERVAR% in b.cmd, and output that in a.cmd – MajorInc Jun 11 '12 at 14:45
1

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

Community
  • 1
  • 1
dbenham
  • 127,446
  • 28
  • 251
  • 390
  • Thanks dbenham, I am actually looking to persist ERRORLEVEL. So b.bat actually is making couple of calling couple of queries via sqlcmd. So I guess in this i should use your example (with CALL) right? (and it wont work with START) – MajorInc Jun 11 '12 at 15:54
  • @MajorInc - You could use START coupled with my first suggestion, but there is no advantage to it. It's more efficient to use CMD directly. I still like calling a modifyed form of b.bat better. – dbenham Jun 11 '12 at 16:01
  • You know what, I think actually something as simple as start /wait cmd /c b.bat works. As you said ERRORLEVEL is an environment variable and therefore is persistance. I think the problem I am facing maybe caused by the "set errorlevel=%errorsaved%" line i have in caller.bat :/ – MajorInc Jun 11 '12 at 17:38