>>> pipe.wait()
42
>>> call('python testexit_sys.py')
Bye sys world
42
>>> pipe = Popen('python testexit_sys.py', stdout=PIPE)
>>> pipe.communicate()
(b'Bye sys world\r\n', None)
>>> pipe.returncode
42
The subprocess module works the same on Unix-like platforms like Cygwin, but unlike
os.popen, the exit status is not encoded, and so it matches the Windows result (note
that shell=True is needed to run this as is on Cygwin and Unix-like platforms, as we
learned in Chapter 2; on Windows this argument is required only to run commands
built into the shell, like dir):
[C:\...\PP4E\System\Exits]$ python
>>> from subprocess import Popen, PIPE, call
>>> pipe = Popen('python testexit_sys.py', stdout=PIPE, shell=True)
>>> pipe.stdout.read()
b'Bye sys world\n'
>>> pipe.wait()
42
>>> call('python testexit_sys.py', shell=True)
Bye sys world
42
Process Exit Status and Shared State
Now, to learn how to obtain the exit status from forked processes, let’s write a simple
forking program: the script in Example 5-17 forks child processes and prints child
process exit statuses returned by os.wait calls in the parent until a “q” is typed at the
console.
Example 5-17. PP4E\System\Exits\testexit_fork.py
"""
fork child processes to watch exit status with os.wait; fork works on Unix
and Cygwin but not standard Windows Python 3.1; note: spawned threads share
globals, but each forked process has its own copy of them (forks share file
descriptors)--exitstat is always the same here but will vary if for threads;
"""
import os
exitstat = 0
def child(): # could os.exit a script here
global exitstat # change this process's global
exitstat += 1 # exit status to parent's wait
Program Exits | 219