status=system('myprog')
on Windows 2000, status is *always* zero afterwards,
even if myprog sets an exit code.
Can someone explain why this is so?
Is there a way to run an external program and get its exit
code on Windows?
Ronald
Do you have a C compiler? Do you know how to use it?
Your syntax throws sytax errors under XP because of the single quotes
instead of the required double quotes. Otherwise, with "", I can't get it
not to work with my test .com program (it returns the ASCII code of a
keypress). You may be using a Windows program or some other that doesn't
return an exit code ... or the zero return may be correct.
This debug script creates GETCH.COM, the above mentioned test program,
a
XOR AX,AX
INT 16
MOV AH,4C
INT 21
rcx
8
ngetch.com
w
q
then
awk "BEGIN{ print system(\"getch\")}"
should display the ASCII code of the letter key you press.
Note that the test .com is very nearly the smallest possible executable
that is actually useful: eight bytes.
--
T.E.D. (tda...@mst.edu)
Do you have by any chance a variable COMSPEC set? If so, what does it
contain?
Actually, it would throw syntax error on *any* platform (even non-
Win),
but for a different reason. The quotes given don't have anything to
do with Windows (the single quotes wouldn't be passed to the OS
either),
it is purely an awk issue: system() expects a string expression, in my
case a string constant, and string constants in awk have to be
delimited
by double quotes. It was my fault not to post my example testprogram,
which would be syntactically accepted. So here we go:
END {
status=system("DIR *.awk")
print "status=",status
status=system("seterlev 4")
print "status=",status
}
seterlev is a program which is supposed to set the exit code
(ERRORLEVEL)
to 4 - more to this below. Executing this awk program with
gawk -f stest.awk <NUL
I get the output
Datenträger in Laufwerk U: ist fischron
Datenträgernummer: 0247-2660
Verzeichnis von U:\develsv\ARTS\playground
14.07.2008 15:18 128 stest.awk
1 Datei(en) 128 Bytes
0 Verzeichnis(se), 2.400.190.464 Bytes frei
status= 0
status= 0
so both system() calls return status 0.
Now you might suspect that seterlev does not set the exit code in the
intended way (I downloaded it from the Net, and it could be buggy).
But I can easily test it with the following Batch file:
seterlev 4
if ERRORLEVEL 4 echo Error Level 4 or greater
When I run this batch file, I get the output
Error Level 4 or greater
so we can trust that seterlev indeed returns the desired exit code.
Ronald
I have not installed a C compiler, but I don't see how this would help
me with my present problem...
Ronald
GNU Awk 3.1.0 (for native Windows, i.e. not Cygwin)
>
> Do you have by any chance a variable COMSPEC set? If so, what does it
> contain?
ComSpec=C:\WINNT\system32\cmd.exe
so this looks good.
Then you need to think a little harder...
--
(^\pop/^)
I'm lost... I've gone to look for myself.
If I should return before I get back, keep me here.
--
As expected for DIR - DIR is a CMD.EXE internal command and does not
return an ERRORLEVEL.
However, that is not the expected return from SETERLEV: (Screen dump)
D:\MyFiles>awk "BEGIN{status = system(\"seterlev 4\"); print status}"
4
I cannot duplicate your problem under XP.
--
T.E.D. (tda...@mst.edu)
That was certainly true under DOS. Probably true under DOS-ish versions
of Windows (i.e., Windows 95/98). Posts from Ted have indicated that it
is no longer true under Windows 2K/XP/beyond (*). I personally have not
tested since about DOS 5 (**). I have rarely had the need to run things
via system() from any version of AWK; I think that proper design of your
batch files and/or shell scripts should render this need (almost)
non-existent.
My earlier comment(s) about having a C compiler were intended to
indicate that whatever/whenever it is doing something you don't like,
you can always get the source, fix it, and re-compile. There's always
that...
(*) Even Microsoft can get it right eventually...
(**) And that was not in the context of running system() from AWK. It
was in the context of "shelling" out from other programs. But the
concept is the same.
run-1:
d:\temp>gawk "BEGIN{exit 11}"
d:\temp>echo %errorlevel%
11
run-2:
d:\temp>gawk "BEGIN{print system(\"gawk \\\"BEGIN{exit 11}\\\"\")}"
0
So I conclude from this that MS hasn't fixed COMSPEC (mine is cmd.exe)
*OR* my versions of gawk is calling an old command.com by default (which
I doubt).
d:\temp>gawk --version
GNU Awk 3.1.6
Copyright (C) 1989, 1991-2007 Free Software Foundation.
test-1:
d:\temp>cmd.exe /c gawk "BEGIN{exit 21}"
d:\temp>echo %errorlevel%
21
test-2:
d:\temp>command.com /c gawk "BEGIN{exit 21}"
d:\temp>echo %errorlevel%
0
above test may indicate the fault is within gawk...
The exactly same code returns for me 0.
Differences are:
- I am using Windows 2000, you are using XP (so maybe Win2000 CMD.EXE
does not pass the exit code back to the calling process, but XP does).
- You are using awk, I am using gawk. In case you didn't just rename
gawk.exe to awk.exe, may I ask you which awk you are using?
Ronald
Actually, I wanted to get rid of batch scripts altogether. But maybe
I'll
drop awk altogether and simply code it in Perl or Ruby.... Main reason
in
favour of awk was that the whole programming language is "implemented
in a single exe file", which is a bonus in my concrete application.
OK, then
I can then maybe use tcsh - I don't like C-Shell programming at all,
but
at least there is a tcsh for Windows and it is (like awk) in one exe
file
and it does get me back the exit code on Win2000....
> My earlier comment(s) about having a C compiler were intended to
> indicate that whatever/whenever it is doing something you don't like,
> you can always get the source, fix it, and re-compile. There's always
> that...
I see; didn't think about that. Thanks, good idea, but not worth the
trouble in my case.
Ronald
Finally someone who can reproduce my findings ;-)
> So I conclude from this that MS hasn't fixed COMSPEC (mine is cmd.exe)
> *OR* my versions of gawk is calling an old command.com by default (which
> I doubt).
Maybe the letter, because of the following:
c:\> cmd /c gawk "BEGIN{exit 11}"
c:\> echo %errorlevel%
11
If it were a problem with cmd.exe (i.e that it would not pass back the
exit code to the calling process), we would see here 0 again; but we
can clearly see the 11.
This would also explain why I can use system() from languages such as
Ruby or Perl without problems.
Ronald
Thanks a lot - I overlooked your followup, but this looks
to me as a reasonable explanation!
Ronald
> - You are using awk, I am using gawk. In case you didn't just rename
> gawk.exe to awk.exe, may I ask you which awk you are using?
>
gawk
Screen dump:
d:\myfiles>awk --version
GNU Awk 3.1.3
Copyright (C) 1989, 1991-2003 Free Software Foundation.
--
T.E.D. (tda...@mst.edu)
Remove the stand alone version and install the real version from
<http://gnuwin32.sourceforge.net/packages/gawk.htm>. Anyway, the DLLs are
used by other GNU utilities you might want.
--
T.E.D. (tda...@mst.edu)
Good explanation, but things get even more strange:
I have followed your advice, but the gawk downloaded here has the
exactly
same problem. Then I found (in gnuwin32) two other awk versions: mawk
and
nawk. When I run mawk, it says that system() is not implemented.
Running
nawk on the program
END {
status=system("DIR *.awk")
print "status=",status
status=system("seterlev 4")
print "status=",status
}
using the command line
nawk -f stest.awk <NUL
I get the following funny output (have a look at the last line!):
===============================================================
Datenträger in Laufwerk U: ist fischron
Datenträgernummer: 0247-2660
Verzeichnis von U:\develsv\ARTS\playground
14.07.2008 15:18 128 stest.awk
14.07.2008 15:30 124 stest1.awk
2 Datei(en) 252 Bytes
0 Verzeichnis(se), 3.351.248.896 Bytes frei
status= 0
status= 0,015625
==============================================================
It gives a status as 0,015625 (whatever this is supposed to mean)...
Ronald
Update: I found yet another awk on
http://plan9.bell-labs.com/cm/cs/who/bwk/awk95.exe
which is different from nawk, but this one too prints the strange
0,015625, so there must be some deeper meaning in it....
Ronald
Keep in mind that this isn't a function of the language per se. I.e.,
it isn't "(g)awk vs., e.g., Ruby or Perl". Rather, it is a function of
which compiler/toolchain/library was used to compile the version of
GAWK-for-Windows that you are using. As Ted has shown, it is possible
for this to work correctly under DOS/Windows (and most of us would get
the same results he did). If you have a version of GAWK-for-Windows
where the system() function invokes COMMAND.COM rather than CMD.EXE (*),
then you have a seriously broken version. And note that I am not
talking about the GAWK "version" as displayed by, e.g., the "-W version"
option (e.g., 3.1.6 or whatever). As noted, I am talking about the
compiler/toolchain/library used in the compile.
(*) Assuming that you _are_ running a version of DOS/Windows that has
CMD.EXE - i.e., not true/pure DOS or Win95/98.
> which is different from nawk, but this one too prints the strange
> 0,015625, so there must be some deeper meaning in it....
It's likely an overflow problem: the program expects a byte return but
CMD.EXE returns are 16 bit words.
--
T.E.D. (tda...@mst.edu)
I get your point. Strangely, the problem even appears when downloading
the binary version from http://gnuwin32.sourceforge.net/, so it would
mean that *this* is already broken :-(
So at the moment, some people discussing in this thread seem to have a
gawk
implementation which works, and some have an implementation which does
not.
Could someone who does have a gawk where the system() call is not
broken,
please let me know where s/he got it?
I've got my binaries from http://gnuwin32.sourceforge.net/packages/gawk.htm
(gawk 3.1.6, version using DLL) and from http://unxutils.sourceforge.net/
(gawk 3.1.0, stand-alone version).
Ronald
It means your program was 1/64 successful :-)
Seriously, the fact the number is 1/64 = 2^-6 should trigger some
thoughts. awk only uses floating point numbers internally and maybe
(this is pure speculation) an integer value from the OS is internally
blindly written into the storage space of a floating point number.
I would look into the binary representation of floating point numbers
and what bit pattern 1/64 is in a floating point number.
/Thomas
Fuzzy Logic! - a great feature 8-)
And using real numbers for exit codes opens as well a much larger
range for potential distinguished error conditions than any 8 (or
16) bit interger could provide ;-)
Janis
At least a sign of hope :-D
> Seriously, the fact the number is 1/64 = 2^-6 should trigger some
> thoughts. awk only uses floating point numbers internally and maybe
> (this is pure speculation) an integer value from the OS is internally
> blindly written into the storage space of a floating point number.
If it were a floating point number, wouldn't then the comma be printed
as a period (.) instead of a comma (,)?
Ronald
$ LANG=de_DE awk 'BEGIN{print 1/3}'
0,333333
$ LANG=en_US awk 'BEGIN{print 1/3}'
0.333333
Depends on the locale.
Janis
>
> Ronald
You live in Germany? You have set your language environment (locale) to
German? Now, what is the decimal separator in Germany? :-)
What does
awk "BEGIN { print 1 / 3 }"
give you?
Set the language environment to US and I wouldn't be surprised to see a
"." in the output.
/Thomas
I hadn't expected that gawk would respect the locale for printing
decimals!
Thanks for pointing this out!
Ronald
Do you remember where you downloaded it? Did you download the
binaries, or did you compile it on your own?
I wonder about the name (awk instead of gawk). Did you rename it,
or was it already the name when you downloaded it?
Ronald
> On Jul 15, 3:30 pm, Ted Davis <tda...@mst.edu> wrote:
>> On Tue, 15 Jul 2008 01:32:05 -0700, Ronny wrote:
>> > - You are using awk, I am using gawk. In case you didn't just rename
>> > gawk.exe to awk.exe, may I ask you which awk you are using?
>>
>> gawk
>>
>> Screen dump:
>> d:\myfiles>awk --version
>> GNU Awk 3.1.3
>
> Do you remember where you downloaded it? Did you download the binaries, or
> did you compile it on your own?
I have already given you the link:
<http://gnuwin32.sourceforge.net/packages/gawk.htm>
I downloaded gawk-3.1.3-2-bin.zip, gawk-3.1.3-2-dep.zip, and
gawk-3.1.3-2-doc.zip (the last one has the gawk.hlp file that is so
useful)
I just noticed it's up to 3.1.6 now - time for an upgrade. 3.1.6 is
different: only two zip files (or the setup package): no -dep.zip.
The \bin directory conains awk.exe, gawk-3.1.6.exe, gawk.exe, igawk,
pgawk-3.1.6.exe, and pgawk.exe (igawk is a Unix shell script - why it's
included in a Windows distro is beyond me). awk.exe gawk-3.1.6, and
gawk.exe are identical, as are the two pgawk files. There is no .hlp file,
but there is a .chm which is more or less the same thing.
>
> I wonder about the name (awk instead of gawk). Did you rename it, or was
> it already the name when you downloaded it?
Some versions come with it - for those that don't, I simply copy gawk.exe
to awk.exe.
Now, the *really* interesting part is that 3.1.6 has your problem and
3.1.3 doesn't. There are no strings (as returned by strings.exe) in any
of the binaries to indicate what compiler package was used.
There seems to be at least one bad compiler out there, but I have no clue
to which it might be. If I had time, which I don't (and won't before the
end of August at the earliest), I'd try compiling the source on some of
those I have access to.
Fortunately, I hardly ever use system(), and where I do, I don't test the
return value ... at least I can't think of a case where I do.
--
T.E.D. (tda...@mst.edu)
That's the point: I did download my gawk from this site (3.1.6),
and this version of gawk has the error.
The only difference is that I did not downloaded the zip file
explicitly, but clicked on the "Setup" link on the page
http://gnuwin32.sourceforge.net/packages/gawk.htm (i.e. the
link which points to http://gnuwin32.sourceforge.net/downlinks/gawk.php),
but unless we assume real evil things going on, this should
yield the very same gawk.
So if you download 3.1.6, it might be that you can also reproduce
the bug I've encountered. If gawk 3.1.6 works on your system, but
doesn't on mine, it must have to do something with my environment,
though I have not the slightest idea what.
> Now, the *really* interesting part is that 3.1.6 has your problem and
> 3.1.3 doesn't. There are no strings (as returned by strings.exe) in any
> of the binaries to indicate what compiler package was used.
May I kindly ask you the favour to send me by mail your version 3.1.3
(plus the
required dll), so that I can try out whether they work for me? Please
send them
to my address at
Thanks a lot!
Ronald
> May I kindly ask you the favour to send me by mail your version 3.1.3
> (plus the
> required dll), so that I can try out whether they work for me? Please
> send them
> to my address at
You can download it yourself from the download page:
http://sourceforge.net/project/showfiles.php?group_id=23617&package_id=16431
You are right. And I just tested it: Version 3.1.3.2 indeed works!!!!
So this means that the bug was introduced somewhere between release
3.1.3.2 and 3.1.6...
Ronald
Needless to say, I can't find the zips anywhere (there may be copies at
home) or setup.exe (I have several older versions). However, older
versions (back to 3.0.4) are still available from sourceforge:
<http://sourceforge.net/project/showfiles.php?group_id=23617&package_id=16431&release_id=220554>
In case that URL is broken, go to the
<http://gnuwin32.sourceforge.net/packages/gawk.htm> page, click on
the "files page" link, then scroll down to 3.1.3. While not identical to
the file I'm using, the gawk.exe in the binaries file does pass the
system("seterlev 4") test. The gawk-3.1.3.exe file on the download page
is the setup program.
--
T.E.D. (tda...@mst.edu)
Assumption correct.
Actually, I had already informed before Aharon Robbins,
who, as far I understand, is one of the maintainers
of gawk.exe, about the bug, but I thought it might not
harm entering it also in the bug database.
Ronald Otto Valentin, a.k.a. Ronny