Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

How to return exit codes from BATs?

2 views
Skip to first unread message

Greg Ercolano

unread,
Jul 20, 2000, 3:00:00 AM7/20/00
to
This seems like such a simple thing..
a way for batch script to return an exit code to the parent process.

In my case, I have a C program that invokes a BAT script,
and I want the BAT to return exit codes to it, based on the
script's logic.

In most shell and programming languages (perl/csh/bash/C/C++)
it's easy; you just say:

exit (code#)

ie. in the CSH:

exit 3 # returns an exit code of 3

But it appears the MSDOS 'exit' command does not take an argument.

How does one return a specific exit code from a DOS batch file
to the invoking process? And does the technique work in all DOS
shells (including WinNT)?

Nothing useful came up when I searched dejanews and the MS
knowledge base.

Thanks in advance..

pat.deaubonne

unread,
Jul 20, 2000, 3:00:00 AM7/20/00
to
Why you don't make a programme ?
Whith just this line;

main(int argc, char**argv)
{
return(atoi ( argv[1] ) );
}

If the name of this prog. is MyReturn.c
Then you use it like this;

C:>MyReturn 2

An error code will be send !

Pat


Greg Ercolano <er...@netcom3.netcom.com> a écrit dans le message :
8l61n1$slr$1...@slb6.atl.mindspring.net...

Matthias Tacke

unread,
Jul 20, 2000, 3:00:00 AM7/20/00
to
That doesn't work because whtat whe wants is an errorcode from the bat-File
called from a C-Program. The Problem is I Think that C really invokes a
new Command-Shell which in turn then executes the Batch. I don't know if
there is a possibility of giving the the termination-Code of a batch to
the terminating Command-Shell. Maybe it works with another Shell like
4dos .

hth

--
Gruß
Matthias Tacke Email: Matt...@Tacke.de
---------+---------+---------+---------+---------+---------+---------+-------

Todd Vargo

unread,
Jul 20, 2000, 3:00:00 AM7/20/00
to
Matthias Tacke <Matt...@Tacke.de> wrote in message
news:8l67an$v1l$12$1...@news.t-online.com...

Assuming the batch is generated by the program each run, you can have the
batch create a flag file in TEMP (or other valid location), which will be
detectable and must be cleaned up in the C code after the shell ends.

--
Todd Vargo

[To email me, body of msg must contain my name]

Greg Ercolano

unread,
Jul 20, 2000, 3:00:00 AM7/20/00
to
>>> Why you don't make a programme ?
>>> main(int argc, char**argv) { return(atoi ( argv[1] ) ); }

>> That doesn't work because what he wants is an errorcode from the bat-File
>> called from a C-Program.

> you can have the batch create a flag file in TEMP (or other valid location),

> which will be detectable and must be cleaned up in the C code after the shell ends.

Uh oh, by these responses something tells me DOS doesn't
provide a straight forward way to do this.

I'm sorta amazed; it seems like the kind of thing MS would have
matured into the language by now; eg. a backwards-compatible
optional numeric argument to EXIT, eg:

EXIT 1
EXIT 2
etc..

Many thanks for all your responses..
Me thinks I'll retreat to using another shell for my little script.

Mike Jones

unread,
Jul 20, 2000, 3:00:00 AM7/20/00
to

You can use pure batch to obtain some errorlevels (e.g. 1 using FIND), but
not generally.
I wrote my own in assembler many years ago (could probably be done in far
fewer bytes, but who worries these days).

or use debug to create a dinky prog for 0-9

debug < exitrc.dbg

exitrc.dbg
----------
Nexitrc.dbg
a100
mov al,[82]
sub al,30
mov ah,4C
int 21

rcx
0A
w
q
-----------


use as

EXITRC 1
EXITRC 2
etc

--
Quench thirst to reply

"Greg Ercolano" <er...@netcom14.netcom.com> wrote in message
news:8l6dmt$9mo$1...@slb3.atl.mindspring.net...

Tom Lavedas

unread,
Jul 20, 2000, 3:00:00 AM7/20/00
to
Batch files can be made to return error codes to other batch files, but
in general, errorlevels are NOT returned through the command processor
back to the parent process. Some versions of DOS did pass the
errorlevels (or rather they forgot to clear the register), but by design
most cleared the errorlevels upon return. I believe NT's (&2000?)
command processor, Cmd.exe, does return the errorlevel.

However, I am assuming the shell() function in C invokes a copy of the
command processor (I am only slightly aware of C's inner workings). If
that is the case, I believe some other means than the Errorlevel is
needed to get the results of a batch procedure back to the 'parent'
program. That is, if it is to operate with more than NT.

Tom Lavedas
-----------
http://www.pressroom.com/~tglbatch/

> Name: SETRC.COM
> SETRC.COM Type: MS-DOS Application (application/x-unknown-content-type-comfile)
> Encoding: x-uuencode

Greg Ercolano

unread,
Jul 21, 2000, 3:00:00 AM7/21/00
to
Whee! I like this one..

Mike Jones <mike...@ntlthirstworld.com> wrote:
> or use debug to create a dinky prog for 0-9
> debug < exitrc.dbg

Guaranteed to work because debug is always around, and no binaries
need to be installed ;)

Ok, I see I just need to get into the spirit of this..

One could run with that and get cute under NT I suppose,
and do something like this to avoid the tmp file:

REM ## Obfiscated DOS Batch Programming Contest ;)
REM ## How to exit a batch script with an error code, V2.0
REM ## NOTE: Values 0-9 are valid (after that, use hex!)
REM ##
IF SOMETHING_HAPPENS set ERR=3
IF SOMETHING_ELSE set ERR=2
( echo a100 & echo mov al,%ERR% & echo mov ah,4c & echo int 21 & echo ^C & echo g ) | debug

NOTE: The ^C in the above is a real control-c character, ie. 0x03.
Sorry, I don't know how to echo a blank line :( Any takers?

If that's the last line in the script, the command processor returns
the exit code returned by DEBUG, ie. the exit code of the assembly program;
woo hoo!

I tested it by writing a C program to invoke it with system("foo.bat"),
and printing the return value; it woiks!

Not sure if that flies on all versions of DOS, but certainly NT/CMD.
Hrm, surely this code won't fly on a Dec Alpha though.. :/


Todd Vargo

unread,
Jul 21, 2000, 3:00:00 AM7/21/00
to
Greg Ercolano <er...@netcom.com> wrote in message
news:8l988g$l17$1...@slb7.atl.mindspring.net...

Your disqualified from the contest! The pipe still creates a temp file. You
just don't know what the filename will be (is / was) because the cleanup is
done behind your back. ;-)


Greg Ercolano

unread,
Jul 21, 2000, 3:00:00 AM7/21/00
to
> ( echo a100 & echo mov al,%ERR% & echo mov ah,4c & echo int 21 & echo ^C & echo g ) | debug
> NOTE: The ^C in the above is a real control-c character, ie. 0x03.
> Sorry, I don't know how to echo a blank line :( Any takers?

That ^C thing was really bugging me, but try as I might,
I could think of no way to echo that blank line 8(

I see one has to be wiley in DOS BAT land, so I think I've got it
licked now by reverting to machine language >8)

---------------------------------------------------------------


REM ## Obfiscated DOS Batch Programming Contest ;)

REM ## How to exit a batch script with an error code, V3.0
REM ## NOTE1: Values 0-9 are valid (after that, use hex!)
REM ## NOTE2: God help you if you forget to set ERR to anything %^O
REM ##
set ERR=0


IF SOMETHING_HAPPENS set ERR=3
IF SOMETHING_ELSE set ERR=2

( echo f 100 105 b8 %ERR% 4c cd 21 & echo g ) | debug
---------------------------------------------------------------

Microsoft, are you watching?

If we're having to write Intel machine language just to return
exit codes from batch scripts, it's a pretty shameful reflection
on your CMD programming + design team.

Please, throw a dime at some programmer to add a few lines of code
to CMD.EXE so EXIT can take an optional numeric argument, and save
the world a few man years of head scratching.

And please, while you're at it, add a flag to ECHO so we can print
blank lines into our assembly language workarounds ;)


laura fairhead

unread,
Jul 21, 2000, 3:00:00 AM7/21/00
to
In article <8l6dmt$9mo$1...@slb3.atl.mindspring.net>,

Greg Ercolano <er...@netcom14.netcom.com> wrote:
> >>> Why you don't make a programme ?
> >>> main(int argc, char**argv) { return(atoi ( argv[1] ) ); }
>
> >> That doesn't work because what he wants is an errorcode from the bat-File
> >> called from a C-Program.
>
> > you can have the batch create a flag file in TEMP (or other valid location),
> > which will be detectable and must be cleaned up in the C code after the shell ends.
>
> Uh oh, by these responses something tells me DOS doesn't
> provide a straight forward way to do this.
>
> I'm sorta amazed; it seems like the kind of thing MS would have
> matured into the language by now; eg. a backwards-compatible
> optional numeric argument to EXIT, eg:
>
> EXIT 1
> EXIT 2
> etc..
>
> Many thanks for all your responses..
> Me thinks I'll retreat to using another shell for my little script.
>

Can't you just use:

ECHO %ERR%|CHOICE /C123456789 /N

Where ERR is set to 1 digit errorlevel you want to return?

L

Sent via Deja.com http://www.deja.com/
Before you buy.

Greg Ercolano

unread,
Jul 21, 2000, 3:00:00 AM7/21/00
to
Todd Vargo <tl...@oh.freei.net> wrote:
> The pipe still creates a temp file. You
> just don't know what the filename will be (is / was) because the cleanup is
> done behind your back. ;-)

True! In good ole DOS, yes, I've caught those left behind
in root directories after rebooting during hung pipe operations.

But since my post probably only works under WinNT DOS,
I don't think they still create pipes with files anymore,
do they? They're probably real pipes by now (?)


Ted Davis

unread,
Jul 21, 2000, 3:00:00 AM7/21/00
to
On Fri, 21 Jul 2000 07:37:33 -0400, "Todd Vargo" <tl...@oh.freei.net>
wrote:

>Your disqualified from the contest! The pipe still creates a temp file. You


>just don't know what the filename will be (is / was) because the cleanup is
>done behind your back. ;-)

NT pipes are not like DOS pipes: they don't seem to use files - the
behavior is more like that of a memory based FIFO buffer.

T.E.D. (tda...@gearbox.maem.umr.edu)
SPAM filter: Messages to this address *must* contain "T.E.D."
somewhere in the body or they will be automatically rejected.

Mike Jones

unread,
Jul 21, 2000, 3:00:00 AM7/21/00
to
I think I have seen this done somewhere else, so I'm reinventing the wheel:
..
if happy set rc=3
if not happy set rc=7
...

echo §%RC%,0-!>_rc_.com
call _rc_
del _rc_.com

----------

Note that this is in-line machine coding in ASCII! - the first char is 0x15
(Alt-21) and the one between the 0 and the ! is 0xCD (Alt-205). It is
therefore CRITICAL that the RC substituted variable is ONLY 1 character
long!

Any improvement welcome!

--
Quench thirst to reply

"Greg Ercolano" <er...@netcom.com> wrote in message
news:8l988g$l17$1...@slb7.atl.mindspring.net...
> Whee! I like this one..
>
> Mike Jones <mike...@ntlthirstworld.com> wrote:
> > or use debug to create a dinky prog for 0-9
> > debug < exitrc.dbg
>
> Guaranteed to work because debug is always around, and no binaries
> need to be installed ;)
>
> Ok, I see I just need to get into the spirit of this..
>
> One could run with that and get cute under NT I suppose,
> and do something like this to avoid the tmp file:
>

> REM ## Obfiscated DOS Batch Programming Contest ;)

> REM ## How to exit a batch script with an error code, V2.0
> REM ## NOTE: Values 0-9 are valid (after that, use hex!)
> REM ##


> IF SOMETHING_HAPPENS set ERR=3
> IF SOMETHING_ELSE set ERR=2

> ( echo a100 & echo mov al,%ERR% & echo mov ah,4c & echo int 21 & echo
^C & echo g ) | debug
>
> NOTE: The ^C in the above is a real control-c character, ie. 0x03.
> Sorry, I don't know how to echo a blank line :( Any takers?
>

Mike Jones

unread,
Jul 21, 2000, 3:00:00 AM7/21/00
to

"laura fairhead" <laura_f...@my-deja.com> wrote in message
news:8l9f3r$8hl$1...@nnrp1.deja.com...

> In article <8l6dmt$9mo$1...@slb3.atl.mindspring.net>,
> Greg Ercolano <er...@netcom14.netcom.com> wrote:
> > >>> Why you don't make a programme ?
[snipped]

> >
> > EXIT 1
> > EXIT 2
> > etc..
> >
> > Many thanks for all your responses..
> > Me thinks I'll retreat to using another shell for my little
script.
> >
>
> Can't you just use:
>
> ECHO %ERR%|CHOICE /C123456789 /N
>
> Where ERR is set to 1 digit errorlevel you want to return?
>

That's far too sensible & easy!

Well spotted. (I can't see the wood for the trees)

Greg Ercolano

unread,
Jul 21, 2000, 3:00:00 AM7/21/00
to
laura fairhead <laura_f...@my-deja.com> wrote:

> Can't you just use:
> ECHO %ERR%|CHOICE /C123456789 /N

Wow, that's almost clear.
Certainly no points in the obfuscation contest for that one. ;)

Unfortunately, when I run CHOICE in a DOS window on my NT,
I get a big ole 'Command Not Found', or well, the equivalent two sentences.

I think CHOICE is part of the optional NT Resource Kit. I don't have it,
and can't guarentee the target machines my script will be used on will
have it either.

BTW, based on a book I found on the NTRK, it appears you might need a ':'
after the /C in CHOICE, ie:

CHOICE /C:123456789

I can't verify that though, I'm just going by the example in my book.

By all rights I shouldn't do the assembly stuff either; it's not portable
across different processors, but I certainly appreciate depths to which
folks must go to get satisfaction. Certainly writing in machine code communicates
the level of frustration better than no other, and I like code that communicates ;)

To be honest, my actual 'in the field' solution to the problem so far
has been this one:

set ERR=2
perl -e exit(%ERR%);

It just so happens in my case there's a dependency on perl elsewhere,
so this sort of works for now, seems the lesser of evils, and definitely
looses the obfuscation contest, because the word 'exit' even appears in the code.

If a more DOS-like solution exists, I'll replace that perl command.


Todd Vargo

unread,
Jul 22, 2000, 3:00:00 AM7/22/00
to
Ted Davis <tda...@gearbox.maem.umr.edu> wrote in message
news:7kjgns4bnqeki5l1k...@4ax.com...


T.E.D.,

I'm sure I have read this once or twice in this group but forgot. As you
know, I know very little about the quirks of NT vs. DOS.

Anyways, I was just going on the original questions...

"How does one return a specific exit code from a DOS batch file
to the invoking process? And does the technique work in all DOS
shells (including WinNT)?"

...I didn't bother to mention his batch was NT specific.

**************************************************

Greg Ercolano,

When we get down to the nitty gritty of the matter, does your C code need to
work in "all DOS shells (including WinNT)" as originally mentioned, or just
in NT alone? The answer to this decides what can or can not to be used in
your code. Also, if using an external utility 'DEBUG.EXE' is considered ok,
what is wrong with just creating a TMP file with some significant value?
This *is* backward compatible, adding new functionality to EXIT, or using OS
specific code is not.

Just my thoughts,
Todd Vargo


Ted Davis

unread,
Jul 22, 2000, 3:00:00 AM7/22/00
to
On Sat, 22 Jul 2000 04:31:27 -0400, "Todd Vargo" <tl...@oh.freei.net>
wrote:

>Ted Davis <tda...@gearbox.maem.umr.edu> wrote in message
>news:7kjgns4bnqeki5l1k...@4ax.com...
>> On Fri, 21 Jul 2000 07:37:33 -0400, "Todd Vargo" <tl...@oh.freei.net>
>> wrote:
>>
>> >Your disqualified from the contest! The pipe still creates a temp file.
>You
>> >just don't know what the filename will be (is / was) because the cleanup
>is
>> >done behind your back. ;-)
>>
>> NT pipes are not like DOS pipes: they don't seem to use files - the
>> behavior is more like that of a memory based FIFO buffer.
>>
>>
>>
>

>T.E.D.,
>
>I'm sure I have read this once or twice in this group but forgot. As you
>know, I know very little about the quirks of NT vs. DOS.
>
>Anyways, I was just going on the original questions...
>
> "How does one return a specific exit code from a DOS batch file
> to the invoking process? And does the technique work in all DOS
> shells (including WinNT)?"
>
>...I didn't bother to mention his batch was NT specific.
>
>**************************************************
>
>Greg Ercolano,
>
>When we get down to the nitty gritty of the matter, does your C code need to
>work in "all DOS shells (including WinNT)" as originally mentioned, or just
>in NT alone? The answer to this decides what can or can not to be used in
>your code. Also, if using an external utility 'DEBUG.EXE' is considered ok,
>what is wrong with just creating a TMP file with some significant value?
>This *is* backward compatible, adding new functionality to EXIT, or using OS
>specific code is not.
>

Am I the only one around here who knows anything about the inner
workings of DOS? There is a provision in the DOS data memory area -
16 bytes, actually - for programs to communicate with each other.
0000:04f0 through 0000:04ff are the InterProcess Communication Area
(IPCA).

It's trivial to read this in C - peek() the location. A simple DEBUG
script lets the batch file return a byte value there. This batch file
returns its hexidecimal 0-ff argument as both an exit code
(ERRORLEVEL) and as the byte at 0000:04f0.

@echo off
echo a > %temp%\setel.src
echo MOV AL,%1 >> %temp%\setel.src
echo MOV AH,4C >> %temp%\setel.src
echo INT 21 >> %temp%\setel.src
echo. >> %temp%\setel.src
echo rcx >> %temp%\setel.src
echo 06 >> %temp%\setel.src
echo w >> %temp%\setel.src
echo e0000:04f0 %1 >> %temp%\setel.src
echo q >> %temp%\setel.src
echo. > %temp%\setel.com
debug %temp%\setel.com < %temp%\setel.src > nul
%temp%\setel
:: del %temp%\setel.*

The last line is particularly interesting: it has to be commented out
for the program to set ERRORLEVEL in NT because it appears that DEL
returns an ERRORLEVEL (as far as I can tell, it always returns 0).
Reports about other operating systems would be appreciated.

This should work in any DOS-like OS after PC/MS-DOS 1.x.

echo e0000:04f0 %1 > %temp%\setel.src
echo q >> %temp%\setel.src
debug < %temp%\setel.src > nul

is all that's needed for just the IPCA write.

I'll do a Web page essay on this. The plan is is to take this
question and address it with the above code, then it's opposite
direction equivilent. I plan to follow that with material on general
memory access, and maybe someday extend it to making batch use of the
DOS data areas and perhaps stuff in The List of Lists, video card
identification ... lots of stuff to be found in memory if you know
where to look and how to look.


T.E.D. (tda...@gearbox.maem.umr.edu - e-mail must contain "batch" in the subject or my .sig in the body)

Greg Ercolano

unread,
Jul 22, 2000, 3:00:00 AM7/22/00
to
Todd Vargo <tl...@oh.freei.net> wrote:
> [..] And does the technique work in all DOS
> shells (including WinNT)?"

> When we get down to the nitty gritty of the matter, does your C code need to


> work in "all DOS shells (including WinNT)" as originally mentioned, or just
> in NT alone?

It must work in all DOS shells, ie. the latest version
of plain old DOS. (not v2.00, but more like 6.x and up)

I was sort of kidding (tongue in cheek) about the DEBUG stuff..

At a certain point duing the thread I realized the (humorous)
levels of hackery depths to which I might have to go to do such
a simple thing, and threfore appreciated the DEBUG approach
it for its directness (and absurdity ;)

I haven't ruled it out either; possibly I could derive some
Dec Alpha code, and conditionally generate Intel or Dec Alpha
machine code.. then I'd have cross platform licked! 8)

In fact, I might do it just because it's more entertaining
than the more correct solution I've decided on, which is to not
use BAT at all, and simply hard code the stuff in my C program,
and make a config file for the user that has a little testing
language built into it.

I see you gotta have a little sense of humor in DOS land,
just to keep sane ;)


laura fairhead

unread,
Dec 6, 2000, 3:00:00 AM12/6/00
to
On 21 Jul 2000 11:50:21 GMT, Greg Ercolano <er...@netcom6.netcom.com> wrote:

>> ( echo a100 & echo mov al,%ERR% & echo mov ah,4c & echo int 21 & echo ^C & echo g ) | debug
>> NOTE: The ^C in the above is a real control-c character, ie. 0x03.
>> Sorry, I don't know how to echo a blank line :( Any takers?
>

> That ^C thing was really bugging me, but try as I might,
> I could think of no way to echo that blank line 8(
>
> I see one has to be wiley in DOS BAT land, so I think I've got it
> licked now by reverting to machine language >8)
>
>---------------------------------------------------------------

>REM ## Obfiscated DOS Batch Programming Contest ;)

>REM ## How to exit a batch script with an error code, V3.0
>REM ## NOTE1: Values 0-9 are valid (after that, use hex!)
>REM ## NOTE2: God help you if you forget to set ERR to anything %^O
>REM ##
>set ERR=0

>IF SOMETHING_HAPPENS set ERR=3
>IF SOMETHING_ELSE set ERR=2

>( echo f 100 105 b8 %ERR% 4c cd 21 & echo g ) | debug
>---------------------------------------------------------------
>
> Microsoft, are you watching?
>
> If we're having to write Intel machine language just to return
> exit codes from batch scripts, it's a pretty shameful reflection
> on your CMD programming + design team.
>
> Please, throw a dime at some programmer to add a few lines of code
> to CMD.EXE so EXIT can take an optional numeric argument, and save
> the world a few man years of head scratching.
>
> And please, while you're at it, add a flag to ECHO so we can print
> blank lines into our assembly language workarounds ;)
>

Can't you just use:-

ECHO %ERR%|CHOICE /C123456789 /N >NUL

Where ERR=digit 1-9, the code you want to return.

L


wd...@my-deja.com

unread,
Dec 8, 2000, 4:23:37 PM12/8/00
to
In article <39783eaa...@openbeta.news.uk.uu.net>,

Hi G & L

Just as an aside. to echo a blank use 'echo.'

W

Todd Vargo

unread,
Dec 8, 2000, 5:10:06 PM12/8/00
to

<wd...@my-deja.com> wrote in message,
[snip]

> > Can't you just use:-
> >
> > ECHO %ERR%|CHOICE /C123456789 /N >NUL
> >
> > Where ERR=digit 1-9, the code you want to return.
> >
> > L
> >
> >
>
> Hi G & L
>
> Just as an aside. to echo a blank use 'echo.'
>
> W

Hi W,

The intent was, at some point in the batch, the variable ERR would be SET
with the desired ERRORLEVEL. Then that value (not a blank) would be ECHOed
to CHOICE to set the actual ERRORLEVEL.

--
Todd Vargo (body of message must contain my name to reply)

0 new messages