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

grabbing return codes from os.system() call

228 views
Skip to first unread message

Damian Menscher

unread,
Mar 8, 2001, 1:20:43 AM3/8/01
to
I'm new to Python (as in, my experience is essentially the tutorial),
but I've already come up with an interesting question:

How do I get the return code from an os.system call? I would have
expected I could do something like

---returncode---
#/bin/csh
echo do stuff
exit 3

and then in my python program I could do

print os.system('./returncode')

But it prints out 768. Not particularly useful, even after I recognize
the trick of dividing by 256 (byte-swapping going on? No, because a
return code of 768 reports as 0). Given that my real return codes
will be (possibly large) integers, this limitation will likely cause
some serious problems down the line.

Even better would be a way of returning a string (the script I run
can be something other than csh, but it has to be a separate script).

Ideas? I'm trying to avoid writing the string out to a file and then
read the file back in to the python program....

Damian Menscher
--
--==## Grad. student & Sys. Admin. @ U. Illinois at Urbana-Champaign ##==--
--==## <mens...@uiuc.edu> www.uiuc.edu/~menscher/ Ofc:(217)333-0038 ##==--
--==## Physics Dept, 1110 W Green, Urbana IL 61801 Fax:(217)333-9819 ##==--

Donn Cave

unread,
Mar 8, 2001, 1:34:32 AM3/8/01
to
Quoth Damian Menscher <mensche...@uiuc.edu>:

| I'm new to Python (as in, my experience is essentially the tutorial),
| but I've already come up with an interesting question:
|
| How do I get the return code from an os.system call? I would have
| expected I could do something like
|
| ---returncode---
| #/bin/csh
| echo do stuff
| exit 3
|
| and then in my python program I could do
|
| print os.system('./returncode')
|
| But it prints out 768. Not particularly useful, even after I recognize
| the trick of dividing by 256 (byte-swapping going on? No, because a
| return code of 768 reports as 0). Given that my real return codes
| will be (possibly large) integers, this limitation will likely cause
| some serious problems down the line.
|
| Even better would be a way of returning a string (the script I run
| can be something other than csh, but it has to be a separate script).
|
| Ideas? I'm trying to avoid writing the string out to a file and then
| read the file back in to the python program....

Your return codes will not be larger than 255, that's all the bits
there are for this kind of thing (on UNIX, anyway.) If you have a
bigger number, you will have to put it somewhere else. So writing
it out to a file might not be such a bad idea.

Donn Cave, do...@oz.net

Gregory Jorgensen

unread,
Mar 8, 2001, 2:02:53 AM3/8/01
to
os.system returns the exit status. The low-order byte of the exit status is the
signal number that killed the process, and the high-order byte is the exit
status (if the signal number is 0). This only works under Unix; on Windows the
exit status is always 0.

768 = 0x0300 -- there's your 3 return value.

This is documented in the Python Library Docs, at:

http://www.python.org/doc/current/lib/os-process.html

You can separate the bytes in many ways. One simple technique:

x = os.system('./returncode')
signal = x & 0xFF
exitcode = (x >> 8) & 0xFF


In article <%wFp6.9481$dL4.1...@vixen.cso.uiuc.edu>, Damian Menscher says...


>
>I'm new to Python (as in, my experience is essentially the tutorial),
>but I've already come up with an interesting question:
>
>How do I get the return code from an os.system call? I would have
>expected I could do something like
>
>---returncode---
>#/bin/csh
>echo do stuff
>exit 3
>
>and then in my python program I could do
>
>print os.system('./returncode')

Greg Jorgensen
Deschooling Society
Portland, Oregon, USA
gr...@pobox.com

Cameron Laird

unread,
Mar 8, 2001, 10:43:33 AM3/8/01
to

Guys, guys; you are making it too hard on Mr. Menscher. My guess
is that he'd appreciate being told that, if he creates /tmp/other
with contents
#!/bin/sh
echo "This is a string from an external process."
he can then have fun with
import os
print os.popen("/tmp/other").read()
--

Cameron Laird <cla...@NeoSoft.com>
Business: http://www.Phaseit.net
Personal: http://starbase.neosoft.com/~claird/home.html

Pat Knight

unread,
Mar 8, 2001, 5:18:10 AM3/8/01
to
Damian Menscher <mensche...@uiuc.edu> writes:

> How do I get the return code from an os.system call? I would have
> expected I could do something like
>
> ---returncode---
> #/bin/csh
> echo do stuff
> exit 3
>
> and then in my python program I could do
>
> print os.system('./returncode')
>
> But it prints out 768. Not particularly useful, even after I recognize
> the trick of dividing by 256 (byte-swapping going on? No, because a

There's no byte swapping. UNIX shifts exit codes up 8 bits to include some
other flags about how a child process exited - normally, seg violation etc.

Look at the process management section of the os module documentation in
Python. This contains functions to decode exit codes.

Also, check the UNIX man pages for system, and the exec, exit and waitpid
system calls. You'll find details of the encoding, and probably find that you
can't have the large exit status values you want.

If you're wanting to return strings or large numbers, start investigating
os.popen.

Cheers,
Pat

Grant Edwards

unread,
Mar 8, 2001, 11:18:44 AM3/8/01
to
In article <%wFp6.9481$dL4.1...@vixen.cso.uiuc.edu>, Damian Menscher wrote:

>How do I get the return code from an os.system call? I would
>have expected I could do something like
>
>---returncode---
>#/bin/csh
>echo do stuff
>exit 3
>
>and then in my python program I could do
>
>print os.system('./returncode')
>
>But it prints out 768. Not particularly useful, even after I
>recognize the trick of dividing by 256 (byte-swapping going on?
>No, because a return code of 768 reports as 0).

A return code of 0x0300 (768) means that the exit status was
0x03, and the signal number was 0x00.

>Given that my real return codes will be (possibly large)
>integers,

They won't be larger than 255. At least not on any Unix system
I've ever heard of.

>this limitation will likely cause some serious problems down
>the line.
>
>Even better would be a way of returning a string (the script I
>run can be something other than csh, but it has to be a
>separate script).

Take a look at the "commands" module. The function
commands.getstatusoutput("foobar") will return a tuple of exit
status, plus stdout and stderr strings. It's just a wrapper
around popen2 routines, so you could do the same thing
yourself. Last time I looked it was only available on Unix
systems.

--
Grant Edwards grante Yow! Bo Derek ruined
at my life!
visi.com

Glenn W Jackman

unread,
Mar 8, 2001, 11:24:49 AM3/8/01
to
Pat Knight wrote:
>Look at the process management section of the os module documentation in
>Python. This contains functions to decode exit codes.
>
>Also, check the UNIX man pages for system, and the exec, exit and waitpid
>system calls. You'll find details of the encoding, and probably find that you
>can't have the large exit status values you want.
>
>If you're wanting to return strings or large numbers, start investigating
>os.popen.

Also have a look at the 'commands' module.

--
Glenn

Mark Hadfield

unread,
Mar 8, 2001, 3:29:45 PM3/8/01
to
"Gregory Jorgensen" <gr...@pobox.com> wrote in message
news:x8Gp6.899$54....@www.newsranger.com...
> os.system returns the exit status. ... on Windows the

> exit status is always 0.

Not so.

On my Win 2000 box with Python 2.0, successful commands return 0 and
unsuccessful commands (where the command is not found) return 1.

Of course there may be more to it, but that's what I found in 20 s of
experimentation...

---
Mark Hadfield
m.had...@niwa.cri.nz http://katipo.niwa.cri.nz/~hadfield
National Institute for Water and Atmospheric Research


Damian Menscher

unread,
Mar 8, 2001, 6:07:57 PM3/8/01
to
Cameron Laird <cla...@starbase.neosoft.com> wrote:
> In article <98795o$kq8$0...@216.39.151.169>, Donn Cave <do...@oz.net> wrote:
>>Quoth Damian Menscher <mensche...@uiuc.edu>:
>>| I'm new to Python (as in, my experience is essentially the tutorial),
>>| but I've already come up with an interesting question:
>>|
>>| How do I get the return code from an os.system call? I would have
>>| expected I could do something like
>>|
>>| ---returncode---
>>| #/bin/csh
>>| echo do stuff
>>| exit 3
>>|
>>| and then in my python program I could do
>>|
>>| print os.system('./returncode')
>>|
>>| But it prints out 768. Not particularly useful, even after I recognize
>>| the trick of dividing by 256 (byte-swapping going on? No, because a
>>| return code of 768 reports as 0). Given that my real return codes
>>| will be (possibly large) integers, this limitation will likely cause
>>| some serious problems down the line.
>>|
>>| Even better would be a way of returning a string (the script I run
>>| can be something other than csh, but it has to be a separate script).
>>|
>>| Ideas? I'm trying to avoid writing the string out to a file and then
>>| read the file back in to the python program....

> Guys, guys; you are making it too hard on Mr. Menscher. My guess


> is that he'd appreciate being told that, if he creates /tmp/other
> with contents
> #!/bin/sh
> echo "This is a string from an external process."
> he can then have fun with
> import os
> print os.popen("/tmp/other").read()

Thank you much -- this solves my problem. I'm sure I'll have more
questions in the near future, though....

David Bolen

unread,
Mar 8, 2001, 10:26:15 PM3/8/01
to
"Mark Hadfield" <m.had...@niwa.cri.nz> writes:

> "Gregory Jorgensen" <gr...@pobox.com> wrote in message
> news:x8Gp6.899$54....@www.newsranger.com...
> > os.system returns the exit status. ... on Windows the
> > exit status is always 0.
>
> Not so.
>
> On my Win 2000 box with Python 2.0, successful commands return 0 and
> unsuccessful commands (where the command is not found) return 1.
>
> Of course there may be more to it, but that's what I found in 20 s of
> experimentation...

The problem is that in order to properly return an exit code of the
child process, the shell in the middle has to pass that information on
up. This is because os.system() will actually start up a child shell
(e.g., something like "/bin/sh" under Unix or typically "command.com"
or "cmd.exe" under Windows), so the actual command being executed is
one layer removed from the Python script.

This is much more reliable under Unix than in my experience under
various command interpreters under various Windows versions, although
NT (I don't yet use 2K consistently) has been reasonably solid.

I've had decent luck with Windows NT and 2K command interpreters
passing up result codes (and the interpreter will generally return 1
if it can't find the command to execute), but recall problems in old
times with Windows 95 command.com, so if that's what the original
poster had, it may account for the consistent 0 return.

It can also be impacted if the command you are going to run is 16-bit,
since that involves other machinery on each Windows version that often
loses the result code along the way. All in all a pain, and best
tested in the environment in which its needed.

--
-- David
--
/-----------------------------------------------------------------------\
\ David Bolen \ E-mail: db...@fitlinxx.com /
| FitLinxx, Inc. \ Phone: (203) 708-5192 |
/ 860 Canal Street, Stamford, CT 06902 \ Fax: (203) 316-5150 \
\-----------------------------------------------------------------------/

Gregory Jorgensen

unread,
Mar 11, 2001, 12:47:01 AM3/11/01
to
In article <x8Gp6.899$54....@www.newsranger.com>, Gregory Jorgensen says...

>
>os.system returns the exit status. The low-order byte of the exit status is the
>signal number that killed the process, and the high-order byte is the exit
>status (if the signal number is 0). This only works under Unix; on Windows the
>exit status is always 0.

Actually the current docs at python.org say that Windows 95 and 98 always return
0. Apparently Windows NT and 2000 do return something. I don't know about Win
ME. The Beazley book "Python Essential Reference" (which I used) says "On
Windows, the exit code is always 0" in the description of os.system.

Tim Peters

unread,
Mar 11, 2001, 1:12:23 AM3/11/01
to pytho...@python.org
[Gregory Jorgensen]

> Actually the current docs at python.org say that Windows 95 and 98
> always return 0. Apparently Windows NT and 2000 do return something.
> I don't know about Win ME. The Beazley book "Python Essential Reference"
> (which I used) says "On Windows, the exit code is always 0" in the
> description of os.system.

On any Windows box,

Python's os.system() calls Microsoft's system().
Microsoft's system() constructs a command line, and
effective executes
%COMSPEC% /c the_command_line
in a new shell.
The return value of the shell (%COMSPEC%) is returned
by Microsoft's system(), which is in turn returned by
Python's os.system().

My Win98SE box is typical of all Win9X systems:

C:\Code>echo %COMSPEC%
C:\WINDOWS\COMMAND.COM

C:\Code>

While it doesn't appear to be documented anywhere, command.com returns 0 no
matter what happens.

NT/Win2K generally use cmd.exe instead, and that returns the same exit code
as the command line it runs.

There is no way to work around the Win9X behavior except via installing a
different DOS shell and setting %COMSPEC% to point to that.


0 new messages