Skip to content

Commit

Permalink
Improve process exit operation
Browse files Browse the repository at this point in the history
.# Discussion

`exit EXITCODE` and `exit /B EXITCODE` do NOT return EXITCODE as the process exit code
unless the batch file is executed with a `call BAT_FILE` command. The ERRORLEVEL *is*
set and returned to the parent shell correctly, but the process exit code *is not*.

For example, given a BAT file "naive-exit-with-error.BAT":

``` batch
:: naive-exit-with-error.BAT
@EXIT /B -1
```

The shell command `call naive-exit-with-error.bat || echo PROCESS_ERROR` will correctly
print "PROCESS_ERROR". However, `naive-exit-with-error.bat || echo PROCESS_ERROR` will
*never* print "PROCESS_ERROR".

This is obviously not controllable by the batch file itself.

So, another method must be used to force both the correct ERRORLEVEL and process exit
code. Notably, a known property of `goto` when jumping to a nonexistent label can be
used to overcome the issue. Per Dave Benham (aka, @dbenham), "GOTO undefined label is a
fatal error. It immediately terminates batch processing, but the currently executing
block of code that has already been parsed continues to completion. However, the
remainder of the code is executed using a command line context instead of a batch
context." This property can be used as in this example:

``` batch
set "exit_val=%ERRORLEVEL%"
goto __nonexistent_label_to_shift_into_command_line_context__ 2>NUL || "%COMSPEC%" /c exit %exit_val%`
```

This batch file code will always return the ERRORLEVEL and a correct corresponding
process exit code, no matter how the batch file is called.

.#### refs

[1] @dbenham's comment on the answer <http://stackoverflow.com/questions/23327304/my-goto-redirect-is-not-working-but-works-with-echo/23327977#23327977>[`@`](http://archive.is/6CgpF)

> GOTO undefined label is a fatal error. It immediately terminates batch processing, but the currently executing block of code that has already been parsed continues to completion. However, the remainder of the code is executed using a command line context instead of a batch context.

[2] <http://stackoverflow.com/questions/4864670/how-to-exit-a-cmd-file-and-the-shell-at-the-same-time/24417241#24417241>[`@`](https://archive.is/X2mkm)

[3] <http://stackoverflow.com/questions/4864670/how-to-exit-a-cmd-file-and-the-shell-at-the-same-time#4876381>[`@`](https://archive.is/X2mkm)

[4] <http://stackoverflow.com/questions/23327304/my-goto-redirect-is-not-working-but-works-with-echo/23335912#23335912>[`@`](https://archive.is/aXJRz)
  • Loading branch information
rivy committed Apr 24, 2019
1 parent 17e5521 commit 9a7db96
Showing 1 changed file with 1 addition and 1 deletion.
2 changes: 1 addition & 1 deletion lib/ExtUtils/PL2Bat.pm
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ EOT
my $tail = <<'EOT';
__END__
:endofperl
@set "ErrorLevel=" & @"%COMSPEC%" /d/c @exit %ErrorLevel%
@set "ErrorLevel=" & @goto _undefined_label_ 2>NUL || @"%COMSPEC%" /d/c @exit %ErrorLevel%
EOT
$tail =~ s/^\s+//gm;

Expand Down

0 comments on commit 9a7db96

Please sign in to comment.