Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

exit /b not working correctly when inside a block with other commands

I have a batch file that needs to be run in a 32-bit context so contains a bit of code to call the 32-bit command processor with its own path. This script also needs to be able to return error code on failure which it does via exit /b 123. However...
When the exit is in a ( ) block, AND contains any statement after it, this does not get returned correctly.

@echo off
setlocal EnableDelayedExpansion

rem Ensure we're running in 32-bit mode
if not %PROCESSOR_ARCHITECTURE%==x86 (
  echo Thunking to 32-bit mode
  %Windir%\SysWOW64\cmd.exe /c %0
  echo !ERRORLEVEL!
  exit /b !ERRORLEVEL!
)

(
  echo before
  exit /b 456
  echo after
)

The output is as follows:

H:\>sub.bat
Thunking to 32-bit mode
before
0

H:\>

If you remove the echo after the exit, then it works exactly as expected.

H:\>sub.bat
Thunking to 32-bit mode
before
456

H:\>

Even if you replace the echo with a rem or any other command, it still fails. If you manually run the 32-bit cmd.exe and run the same script, the exit code gets set correctly.

H:\>sub.bat
before

H:\>echo %ERRORLEVEL%
456

H:\>

Can anyone give an explanation and a workaround for this?

like image 486
Deanna Avatar asked Dec 11 '15 15:12

Deanna


People also ask

What is exit b1?

EXIT /b has the option to set a specific exit code, EXIT /b 0 for sucess, EXIT /b 1 (or greater) for an error. The exit code can be an integer of up to 10 digits in length (positive or negative). EXIT without an ExitCode acts the same as goto:eof and will not alter the ERRORLEVEL.

What does exit B mean?

EXIT /B at the end of the batch file will stop execution of a batch file. use EXIT /B < exitcodes > at the end of the batch file to return custom return codes. Environment variable %ERRORLEVEL% contains the latest errorlevel in the batch file, which is the latest error codes from the last command executed.

How do I make a batch file terminate upon encountering an error?

Check the errorlevel in an if statement, and then exit /b (exit the batch file only, not the entire cmd.exe process) for values other than 0.

What does exit do in CMD?

Exit syntax Quits the CMD. EXE program (command interpreter) or the current batch script. Specifies to exit the current batch script instead of CMD. EXE.


1 Answers

The use of the /b switch in the "else" part of the script is causing the exit code to be lost by the second instance of cmd.exe.

When the second instance of the batch file is executed from Syswow64, it will be exiting with the code of 456. Its parent cmd.exe will receive this exit code but has no interest in preserving it. The cmd.exe was able to successfully run the batch and thus exits with 0, back to the first instance.

If you omit the /b switch in the "else" part of the script, this forces the batch file to quit its parent cmd.exe, rather than just finish processing. As the cmd.exe is then told to quit with the 456 exit code, this will be preserved.

The help text for "exit" does infer this behaviour, but it doesn't seem very obvious until you read it with this in mind!

like image 193
Adam Piggott Avatar answered Sep 19 '22 05:09

Adam Piggott