Python subprocess error code

Execute a child program in a new process. On POSIX, the class uses os.execvp()-like behavior to execute the child program. On Windows, the class uses the Windows CreateProcess() function. The arguments to Popen are as follows.

Execute a child program in a new process. On POSIX, the class uses
os.execvp()-like behavior to execute the child program. On Windows,
the class uses the Windows CreateProcess() function. The arguments to
Popen are as follows.

args should be a sequence of program arguments or else a single string.
By default, the program to execute is the first item in args if args is
a sequence. If args is a string, the interpretation is
platform-dependent and described below. See the shell and executable
arguments for additional differences from the default behavior. Unless
otherwise stated, it is recommended to pass args as a sequence.

On POSIX, if args is a string, the string is interpreted as the name or
path of the program to execute. However, this can only be done if not
passing arguments to the program.

Note

shlex.split() can be useful when determining the correct
tokenization for args, especially in complex cases:

>>> import shlex, subprocess
>>> command_line = input()
/bin/vikings -input eggs.txt -output "spam spam.txt" -cmd "echo '$MONEY'"
>>> args = shlex.split(command_line)
>>> print(args)
['/bin/vikings', '-input', 'eggs.txt', '-output', 'spam spam.txt', '-cmd', "echo '$MONEY'"]
>>> p = subprocess.Popen(args) # Success!

Note in particular that options (such as -input) and arguments (such
as eggs.txt) that are separated by whitespace in the shell go in separate
list elements, while arguments that need quoting or backslash escaping when
used in the shell (such as filenames containing spaces or the echo command
shown above) are single list elements.

On Windows, if args is a sequence, it will be converted to a string in a
manner described in Converting an argument sequence to a string on Windows. This is because
the underlying CreateProcess() operates on strings.

The shell argument (which defaults to False) specifies whether to use
the shell as the program to execute. If shell is True, it is
recommended to pass args as a string rather than as a sequence.

On POSIX with shell=True, the shell defaults to /bin/sh. If
args is a string, the string specifies the command
to execute through the shell. This means that the string must be
formatted exactly as it would be when typed at the shell prompt. This
includes, for example, quoting or backslash escaping filenames with spaces in
them. If args is a sequence, the first item specifies the command string, and
any additional items will be treated as additional arguments to the shell
itself. That is to say, Popen does the equivalent of:

Popen(['/bin/sh', '-c', args[0], args[1], ...])

On Windows with shell=True, the COMSPEC environment variable
specifies the default shell. The only time you need to specify
shell=True on Windows is when the command you wish to execute is built
into the shell (e.g. dir or copy). You do not need
shell=True to run a batch file or console-based executable.

Note

Read the Security Considerations section before using shell=True.

bufsize will be supplied as the corresponding argument to the
open() function when creating the stdin/stdout/stderr pipe
file objects:

  • 0 means unbuffered (read and write are one
    system call and can return short)
  • 1 means line buffered
    (only usable if universal_newlines=True i.e., in a text mode)
  • any other positive value means use a buffer of approximately that
    size
  • negative bufsize (the default) means the system default of
    io.DEFAULT_BUFFER_SIZE will be used.

Changed in version 3.3.1: bufsize now defaults to -1 to enable buffering by default to match the
behavior that most code expects. In versions prior to Python 3.2.4 and
3.3.1 it incorrectly defaulted to 0 which was unbuffered
and allowed short reads. This was unintentional and did not match the
behavior of Python 2 as most code expected.

The executable argument specifies a replacement program to execute. It
is very seldom needed. When shell=False, executable replaces the
program to execute specified by args. However, the original args is
still passed to the program. Most programs treat the program specified
by args as the command name, which can then be different from the program
actually executed. On POSIX, the args name
becomes the display name for the executable in utilities such as
ps. If shell=True, on POSIX the executable argument
specifies a replacement shell for the default /bin/sh.

stdin, stdout and stderr specify the executed program’s standard input,
standard output and standard error file handles, respectively. Valid values
are PIPE, DEVNULL, an existing file descriptor (a positive
integer), an existing file object, and None. PIPE
indicates that a new pipe to the child should be created. DEVNULL
indicates that the special file os.devnull will be used. With the
default settings of None, no redirection will occur; the child’s file
handles will be inherited from the parent. Additionally, stderr can be
STDOUT, which indicates that the stderr data from the applications
should be captured into the same file handle as for stdout.

If preexec_fn is set to a callable object, this object will be called in the
child process just before the child is executed.
(POSIX only)

Warning

The preexec_fn parameter is not safe to use in the presence of threads
in your application. The child process could deadlock before exec is
called.
If you must use it, keep it trivial! Minimize the number of libraries
you call into.

Note

If you need to modify the environment for the child use the env
parameter rather than doing it in a preexec_fn.
The start_new_session parameter can take the place of a previously
common use of preexec_fn to call os.setsid() in the child.

If close_fds is true, all file descriptors except 0, 1 and
2 will be closed before the child process is executed. (POSIX only).
The default varies by platform: Always true on POSIX. On Windows it is
true when stdin/stdout/stderr are None, false otherwise.
On Windows, if close_fds is true then no handles will be inherited by the
child process. Note that on Windows, you cannot set close_fds to true and
also redirect the standard handles by setting stdin, stdout or stderr.

Changed in version 3.2: The default for close_fds was changed from False to
what is described above.

pass_fds is an optional sequence of file descriptors to keep open
between the parent and child. Providing any pass_fds forces
close_fds to be True. (POSIX only)

New in version 3.2: The pass_fds parameter was added.

If cwd is not None, the function changes the working directory to
cwd before executing the child. cwd can be a str and
path-like object. In particular, the function
looks for executable (or for the first item in args) relative to cwd
if the executable path is a relative path.

Changed in version 3.6: cwd parameter accepts a path-like object.

If restore_signals is true (the default) all signals that Python has set to
SIG_IGN are restored to SIG_DFL in the child process before the exec.
Currently this includes the SIGPIPE, SIGXFZ and SIGXFSZ signals.
(POSIX only)

Changed in version 3.2: restore_signals was added.

If start_new_session is true the setsid() system call will be made in the
child process prior to the execution of the subprocess. (POSIX only)

Changed in version 3.2: start_new_session was added.

If env is not None, it must be a mapping that defines the environment
variables for the new process; these are used instead of the default
behavior of inheriting the current process’ environment.

Note

If specified, env must provide any variables required for the program to
execute. On Windows, in order to run a side-by-side assembly the
specified env must include a valid SystemRoot.

If encoding or errors are specified, the file objects stdin, stdout
and stderr are opened in text mode with the specified encoding and
errors, as described above in Frequently Used Arguments. If
universal_newlines is True, they are opened in text mode with default
encoding. Otherwise, they are opened as binary streams.

New in version 3.6: encoding and errors were added.

If given, startupinfo will be a STARTUPINFO object, which is
passed to the underlying CreateProcess function.
creationflags, if given, can be one or more of the following flags:

  • CREATE_NEW_CONSOLE
  • CREATE_NEW_PROCESS_GROUP
  • ABOVE_NORMAL_PRIORITY_CLASS
  • BELOW_NORMAL_PRIORITY_CLASS
  • HIGH_PRIORITY_CLASS
  • IDLE_PRIORITY_CLASS
  • NORMAL_PRIORITY_CLASS
  • REALTIME_PRIORITY_CLASS
  • CREATE_NO_WINDOW
  • DETACHED_PROCESS
  • CREATE_DEFAULT_ERROR_MODE
  • CREATE_BREAKAWAY_FROM_JOB

Popen objects are supported as context managers via the with statement:
on exit, standard file descriptors are closed, and the process is waited for.

with Popen(["ifconfig"], stdout=PIPE) as proc:
    log.write(proc.stdout.read())

Changed in version 3.2: Added context manager support.

Changed in version 3.6: Popen destructor now emits a ResourceWarning warning if the child
process is still running.

Purpose: Start and communicate with additional processes.

The subprocess module supports three APIs for working with
processes. The run() function, added in Python 3.5, is a
high-level API for running a process and optionally collecting its
output. The functions call(), check_call(), and
check_output() are the former high-level API, carried over from
Python 2. They are still supported and widely used in existing
programs. The class Popen is a low-level API used to build
the other APIs and useful for more complex process interactions. The
constructor for Popen takes arguments to set up the new
process so the parent can communicate with it via pipes. It provides
all of the functionality of the other modules and functions it
replaces, and more. The API is consistent for all uses, and many of
the extra steps of overhead needed (such as closing extra file
descriptors and ensuring the pipes are closed) are “built in” instead
of being handled by the application code separately.

The subprocess module is intended to replace functions such as
os.system(), os.spawnv(), the variations of popen()
in the os and popen2 modules, as well as the
commands() module. To make it easier to compare
subprocess with those other modules, many of the examples in
this section re-create the ones used for os and popen2.

Note

The API for working on Unix and Windows is roughly the same, but
the underlying implementation is different because of the
difference in process models in the operating systems. All of the
examples shown here were tested on Mac OS X. Behavior on a
non-Unix OS may vary.

Running External Command¶

To run an external command without interacting with it in the same way
as os.system(), use the run() function.

subprocess_os_system.py

import subprocess

completed = subprocess.run(['ls', '-1'])
print('returncode:', completed.returncode)

The command line arguments are passed as a list of strings, which
avoids the need for escaping quotes or other special characters that
might be interpreted by the shell. run() returns a
CompletedProcess instance, with information about the process
like the exit code and output.

$ python3 subprocess_os_system.py

index.rst
interaction.py
repeater.py
signal_child.py
signal_parent.py
subprocess_check_output_error_trap_output.py
subprocess_os_system.py
subprocess_pipes.py
subprocess_popen2.py
subprocess_popen3.py
subprocess_popen4.py
subprocess_popen_read.py
subprocess_popen_write.py
subprocess_run_check.py
subprocess_run_output.py
subprocess_run_output_error.py
subprocess_run_output_error_suppress.py
subprocess_run_output_error_trap.py
subprocess_shell_variables.py
subprocess_signal_parent_shell.py
subprocess_signal_setpgrp.py
returncode: 0

Setting the shell argument to a true value causes subprocess
to spawn an intermediate shell process which then runs the
command. The default is to run the command directly.

subprocess_shell_variables.py

import subprocess

completed = subprocess.run('echo $HOME', shell=True)
print('returncode:', completed.returncode)

Using an intermediate shell means that variables, glob patterns, and
other special shell features in the command string are processed
before the command is run.

$ python3 subprocess_shell_variables.py

/Users/dhellmann
returncode: 0

Note

Using run() without passing check=True is equivalent to
using call(), which only returned the exit code from the
process.

Error Handling¶

The returncode attribute of the CompletedProcess is the
exit code of the program. The caller is responsible for interpreting
it to detect errors. If the check argument to run() is
True, the exit code is checked and if it indicates an error
happened then a CalledProcessError exception is raised.

subprocess_run_check.py

import subprocess

try:
    subprocess.run(['false'], check=True)
except subprocess.CalledProcessError as err:
    print('ERROR:', err)

The false command always exits with a non-zero status code,
which run() interprets as an error.

$ python3 subprocess_run_check.py

ERROR: Command '['false']' returned non-zero exit status 1

Note

Passing check=True to run() makes it equivalent to using
check_call().

Capturing Output¶

The standard input and output channels for the process started by
run() are bound to the parent’s input and output. That means
the calling program cannot capture the output of the command. Pass
PIPE for the stdout and stderr arguments to capture
the output for later processing.

subprocess_run_output.py

import subprocess

completed = subprocess.run(
    ['ls', '-1'],
    stdout=subprocess.PIPE,
)
print('returncode:', completed.returncode)
print('Have {} bytes in stdout:n{}'.format(
    len(completed.stdout),
    completed.stdout.decode('utf-8'))
)

The ls -1 command runs successfully, so the text it prints to
standard output is captured and returned.

$ python3 subprocess_run_output.py

returncode: 0
Have 522 bytes in stdout:
index.rst
interaction.py
repeater.py
signal_child.py
signal_parent.py
subprocess_check_output_error_trap_output.py
subprocess_os_system.py
subprocess_pipes.py
subprocess_popen2.py
subprocess_popen3.py
subprocess_popen4.py
subprocess_popen_read.py
subprocess_popen_write.py
subprocess_run_check.py
subprocess_run_output.py
subprocess_run_output_error.py
subprocess_run_output_error_suppress.py
subprocess_run_output_error_trap.py
subprocess_shell_variables.py
subprocess_signal_parent_shell.py
subprocess_signal_setpgrp.py

Note

Passing check=True and setting stdout to PIPE is
equivalent to using check_output().

The next example runs a series of commands in a sub-shell. Messages are
sent to standard output and standard error before the commands exit
with an error code.

subprocess_run_output_error.py

import subprocess

try:
    completed = subprocess.run(
        'echo to stdout; echo to stderr 1>&2; exit 1',
        check=True,
        shell=True,
        stdout=subprocess.PIPE,
    )
except subprocess.CalledProcessError as err:
    print('ERROR:', err)
else:
    print('returncode:', completed.returncode)
    print('Have {} bytes in stdout: {!r}'.format(
        len(completed.stdout),
        completed.stdout.decode('utf-8'))
    )

The message to standard error is printed to the console, but the
message to standard output is hidden.

$ python3 subprocess_run_output_error.py

to stderr
ERROR: Command 'echo to stdout; echo to stderr 1>&2; exit 1'
returned non-zero exit status 1

To prevent error messages from commands run through
run() from being written to the console, set the
stderr parameter to the constant PIPE.

subprocess_run_output_error_trap.py

import subprocess

try:
    completed = subprocess.run(
        'echo to stdout; echo to stderr 1>&2; exit 1',
        shell=True,
        stdout=subprocess.PIPE,
        stderr=subprocess.PIPE,
    )
except subprocess.CalledProcessError as err:
    print('ERROR:', err)
else:
    print('returncode:', completed.returncode)
    print('Have {} bytes in stdout: {!r}'.format(
        len(completed.stdout),
        completed.stdout.decode('utf-8'))
    )
    print('Have {} bytes in stderr: {!r}'.format(
        len(completed.stderr),
        completed.stderr.decode('utf-8'))
    )

This example does not set check=True so the output of the command
is captured and printed.

$ python3 subprocess_run_output_error_trap.py

returncode: 1
Have 10 bytes in stdout: 'to stdoutn'
Have 10 bytes in stderr: 'to stderrn'

To capture error messages when using check_output(), set
stderr to STDOUT, and the messages will be merged with
the rest of the output from the command.

subprocess_check_output_error_trap_output.py

import subprocess

try:
    output = subprocess.check_output(
        'echo to stdout; echo to stderr 1>&2',
        shell=True,
        stderr=subprocess.STDOUT,
    )
except subprocess.CalledProcessError as err:
    print('ERROR:', err)
else:
    print('Have {} bytes in output: {!r}'.format(
        len(output),
        output.decode('utf-8'))
    )

The order of output may vary, depending on how buffering is applied to
the standard output stream and how much data is being printed.

$ python3 subprocess_check_output_error_trap_output.py

Have 20 bytes in output: 'to stdoutnto stderrn'

Suppressing Output¶

For cases where the output should not be shown or captured, use
DEVNULL to suppress an output stream. This example suppresses
both the standard output and error streams.

subprocess_run_output_error_suppress.py

import subprocess

try:
    completed = subprocess.run(
        'echo to stdout; echo to stderr 1>&2; exit 1',
        shell=True,
        stdout=subprocess.DEVNULL,
        stderr=subprocess.DEVNULL,
    )
except subprocess.CalledProcessError as err:
    print('ERROR:', err)
else:
    print('returncode:', completed.returncode)
    print('stdout is {!r}'.format(completed.stdout))
    print('stderr is {!r}'.format(completed.stderr))

The name DEVNULL comes from the Unix special device file,
/dev/null, which responds with end-of-file when opened for reading
and receives but ignores any amount of input when writing.

$ python3 subprocess_run_output_error_suppress.py

returncode: 1
stdout is None
stderr is None

Working with Pipes Directly¶

The functions run(), call(), check_call(), and
check_output() are wrappers around the Popen class.
Using Popen directly gives more control over how the command
is run, and how its input and output streams are processed. For
example, by passing different arguments for stdin, stdout, and
stderr it is possible to mimic the variations of os.popen().

One-way Communication With a Process¶

To run a process and read all of its output, set the stdout value to
PIPE and call communicate().

subprocess_popen_read.py

import subprocess

print('read:')
proc = subprocess.Popen(
    ['echo', '"to stdout"'],
    stdout=subprocess.PIPE,
)
stdout_value = proc.communicate()[0].decode('utf-8')
print('stdout:', repr(stdout_value))

This is similar to the way popen() works, except that the
reading is managed internally by the Popen instance.

$ python3 subprocess_popen_read.py

read:
stdout: '"to stdout"n'

To set up a pipe to allow the calling program to write data to it, set
stdin to PIPE.

subprocess_popen_write.py

import subprocess

print('write:')
proc = subprocess.Popen(
    ['cat', '-'],
    stdin=subprocess.PIPE,
)
proc.communicate('stdin: to stdinn'.encode('utf-8'))

To send data to the standard input channel of the process one time,
pass the data to communicate(). This is similar to using
popen() with mode 'w'.

$ python3 -u subprocess_popen_write.py

write:
stdin: to stdin

Bi-directional Communication With a Process¶

To set up the Popen instance for reading and writing at the
same time, use a combination of the previous techniques.

subprocess_popen2.py

import subprocess

print('popen2:')

proc = subprocess.Popen(
    ['cat', '-'],
    stdin=subprocess.PIPE,
    stdout=subprocess.PIPE,
)
msg = 'through stdin to stdout'.encode('utf-8')
stdout_value = proc.communicate(msg)[0].decode('utf-8')
print('pass through:', repr(stdout_value))

This sets up the pipe to mimic popen2().

$ python3 -u subprocess_popen2.py

popen2:
pass through: 'through stdin to stdout'

Capturing Error Output¶

It is also possible watch both of the streams for stdout and stderr,
as with popen3().

subprocess_popen3.py

import subprocess

print('popen3:')
proc = subprocess.Popen(
    'cat -; echo "to stderr" 1>&2',
    shell=True,
    stdin=subprocess.PIPE,
    stdout=subprocess.PIPE,
    stderr=subprocess.PIPE,
)
msg = 'through stdin to stdout'.encode('utf-8')
stdout_value, stderr_value = proc.communicate(msg)
print('pass through:', repr(stdout_value.decode('utf-8')))
print('stderr      :', repr(stderr_value.decode('utf-8')))

Reading from stderr works the same as with stdout. Passing
PIPE tells Popen to attach to the channel, and
communicate() reads all of the data from it before returning.

$ python3 -u subprocess_popen3.py

popen3:
pass through: 'through stdin to stdout'
stderr      : 'to stderrn'

Combining Regular and Error Output¶

To direct the error output from the process to its standard output
channel, use STDOUT for stderr instead of PIPE.

subprocess_popen4.py

import subprocess

print('popen4:')
proc = subprocess.Popen(
    'cat -; echo "to stderr" 1>&2',
    shell=True,
    stdin=subprocess.PIPE,
    stdout=subprocess.PIPE,
    stderr=subprocess.STDOUT,
)
msg = 'through stdin to stdoutn'.encode('utf-8')
stdout_value, stderr_value = proc.communicate(msg)
print('combined output:', repr(stdout_value.decode('utf-8')))
print('stderr value   :', repr(stderr_value))

Combining the output in this way is similar to how popen4()
works.

$ python3 -u subprocess_popen4.py

popen4:
combined output: 'through stdin to stdoutnto stderrn'
stderr value   : None

Connecting Segments of a Pipe¶

Multiple commands can be connected into a pipeline, similar to the
way the Unix shell works, by creating separate Popen
instances and chaining their inputs and outputs together. The
stdout attribute of one Popen instance is used as the
stdin argument for the next in the pipeline, instead of the constant
PIPE. The output is read from the stdout handle for
the final command in the pipeline.

subprocess_pipes.py

import subprocess

cat = subprocess.Popen(
    ['cat', 'index.rst'],
    stdout=subprocess.PIPE,
)

grep = subprocess.Popen(
    ['grep', '.. literalinclude::'],
    stdin=cat.stdout,
    stdout=subprocess.PIPE,
)

cut = subprocess.Popen(
    ['cut', '-f', '3', '-d:'],
    stdin=grep.stdout,
    stdout=subprocess.PIPE,
)

end_of_pipe = cut.stdout

print('Included files:')
for line in end_of_pipe:
    print(line.decode('utf-8').strip())

The example reproduces the command line:

$ cat index.rst | grep ".. literalinclude" | cut -f 3 -d:

The pipeline reads the reStructuredText source file for this section
and finds all of the lines that include other files, then prints the
names of the files being included.

$ python3 -u subprocess_pipes.py

Included files:
subprocess_os_system.py
subprocess_shell_variables.py
subprocess_run_check.py
subprocess_run_output.py
subprocess_run_output_error.py
subprocess_run_output_error_trap.py
subprocess_check_output_error_trap_output.py
subprocess_run_output_error_suppress.py
subprocess_popen_read.py
subprocess_popen_write.py
subprocess_popen2.py
subprocess_popen3.py
subprocess_popen4.py
subprocess_pipes.py
repeater.py
interaction.py
signal_child.py
signal_parent.py
subprocess_signal_parent_shell.py
subprocess_signal_setpgrp.py

Interacting with Another Command¶

All of the previous examples assume a limited amount of
interaction. The communicate() method reads all of the output
and waits for child process to exit before returning. It is also
possible to write to and read from the individual pipe handles used by
the Popen instance incrementally, as the program runs. A
simple echo program that reads from standard input and writes to
standard output illustrates this technique.

The script repeater.py is used as the child process in the next
example. It reads from stdin and writes the values to stdout, one
line at a time until there is no more input. It also writes a message
to stderr when it starts and stops, showing the lifetime of
the child process.

repeater.py

import sys

sys.stderr.write('repeater.py: startingn')
sys.stderr.flush()

while True:
    next_line = sys.stdin.readline()
    sys.stderr.flush()
    if not next_line:
        break
    sys.stdout.write(next_line)
    sys.stdout.flush()

sys.stderr.write('repeater.py: exitingn')
sys.stderr.flush()

The next interaction example uses the stdin and stdout
file handles owned by the Popen instance in different
ways. In the first example, a sequence of five numbers are written to
stdin of the process, and after each write the next line of
output is read back. In the second example, the same five numbers are
written but the output is read all at once using
communicate().

interaction.py

import io
import subprocess

print('One line at a time:')
proc = subprocess.Popen(
    'python3 repeater.py',
    shell=True,
    stdin=subprocess.PIPE,
    stdout=subprocess.PIPE,
)
stdin = io.TextIOWrapper(
    proc.stdin,
    encoding='utf-8',
    line_buffering=True,  # send data on newline
)
stdout = io.TextIOWrapper(
    proc.stdout,
    encoding='utf-8',
)
for i in range(5):
    line = '{}n'.format(i)
    stdin.write(line)
    output = stdout.readline()
    print(output.rstrip())
remainder = proc.communicate()[0].decode('utf-8')
print(remainder)

print()
print('All output at once:')
proc = subprocess.Popen(
    'python3 repeater.py',
    shell=True,
    stdin=subprocess.PIPE,
    stdout=subprocess.PIPE,
)
stdin = io.TextIOWrapper(
    proc.stdin,
    encoding='utf-8',
)
for i in range(5):
    line = '{}n'.format(i)
    stdin.write(line)
stdin.flush()

output = proc.communicate()[0].decode('utf-8')
print(output)

The "repeater.py: exiting" lines come at different points in the
output for each loop style.

$ python3 -u interaction.py

One line at a time:
repeater.py: starting
0
1
2
3
4
repeater.py: exiting


All output at once:
repeater.py: starting
repeater.py: exiting
0
1
2
3
4

Signaling Between Processes¶

The process management examples for the os module include a
demonstration of signaling between processes using os.fork() and
os.kill(). Since each Popen instance provides a pid
attribute with the process id of the child process, it is possible to
do something similar with subprocess. The next example combines
two scripts. This child process sets up a signal handler for the
USR signal.

signal_child.py

import os
import signal
import time
import sys

pid = os.getpid()
received = False


def signal_usr1(signum, frame):
    "Callback invoked when a signal is received"
    global received
    received = True
    print('CHILD {:>6}: Received USR1'.format(pid))
    sys.stdout.flush()


print('CHILD {:>6}: Setting up signal handler'.format(pid))
sys.stdout.flush()
signal.signal(signal.SIGUSR1, signal_usr1)
print('CHILD {:>6}: Pausing to wait for signal'.format(pid))
sys.stdout.flush()
time.sleep(3)

if not received:
    print('CHILD {:>6}: Never received signal'.format(pid))

This script runs as the parent process. It starts
signal_child.py, then sends the USR1 signal.

signal_parent.py

import os
import signal
import subprocess
import time
import sys

proc = subprocess.Popen(['python3', 'signal_child.py'])
print('PARENT      : Pausing before sending signal...')
sys.stdout.flush()
time.sleep(1)
print('PARENT      : Signaling child')
sys.stdout.flush()
os.kill(proc.pid, signal.SIGUSR1)

The output is:

$ python3 signal_parent.py

PARENT      : Pausing before sending signal...
CHILD  26976: Setting up signal handler
CHILD  26976: Pausing to wait for signal
PARENT      : Signaling child
CHILD  26976: Received USR1

Process Groups / Sessions¶

If the process created by Popen spawns sub-processes, those
children will not receive any signals sent to the parent. That means
when using the shell argument to Popen it will be difficult
to cause the command started in the shell to terminate by sending
SIGINT or SIGTERM.

subprocess_signal_parent_shell.py

import os
import signal
import subprocess
import tempfile
import time
import sys

script = '''#!/bin/sh
echo "Shell script in process $$"
set -x
python3 signal_child.py
'''
script_file = tempfile.NamedTemporaryFile('wt')
script_file.write(script)
script_file.flush()

proc = subprocess.Popen(['sh', script_file.name])
print('PARENT      : Pausing before signaling {}...'.format(
    proc.pid))
sys.stdout.flush()
time.sleep(1)
print('PARENT      : Signaling child {}'.format(proc.pid))
sys.stdout.flush()
os.kill(proc.pid, signal.SIGUSR1)
time.sleep(3)

The pid used to send the signal does not match the pid of the child of
the shell script waiting for the signal, because in this example there
are three separate processes interacting:

  1. The program subprocess_signal_parent_shell.py
  2. The shell process running the script created by the main python
    program
  3. The program signal_child.py
$ python3 subprocess_signal_parent_shell.py

PARENT      : Pausing before signaling 26984...
Shell script in process 26984
+ python3 signal_child.py
CHILD  26985: Setting up signal handler
CHILD  26985: Pausing to wait for signal
PARENT      : Signaling child 26984
CHILD  26985: Never received signal

To send signals to descendants without knowing their process id, use a
process group to associate the children so they can be signaled
together. The process group is created with os.setpgrp(),
which sets process group id to the process id of the current process.
All child processes inherit their process group from their parent, and
since it should only be set in the shell created by Popen
and its descendants, os.setpgrp() should not be called in the
same process where the Popen is created. Instead, the
function is passed to Popen as the preexec_fn argument so
it is run after the fork() inside the new process, before it
uses exec() to run the shell. To signal the entire process
group, use os.killpg() with the pid value from the
Popen instance.

subprocess_signal_setpgrp.py

import os
import signal
import subprocess
import tempfile
import time
import sys


def show_setting_prgrp():
    print('Calling os.setpgrp() from {}'.format(os.getpid()))
    os.setpgrp()
    print('Process group is now {}'.format(os.getpgrp()))
    sys.stdout.flush()


script = '''#!/bin/sh
echo "Shell script in process $$"
set -x
python3 signal_child.py
'''
script_file = tempfile.NamedTemporaryFile('wt')
script_file.write(script)
script_file.flush()

proc = subprocess.Popen(
    ['sh', script_file.name],
    preexec_fn=show_setting_prgrp,
)
print('PARENT      : Pausing before signaling {}...'.format(
    proc.pid))
sys.stdout.flush()
time.sleep(1)
print('PARENT      : Signaling process group {}'.format(
    proc.pid))
sys.stdout.flush()
os.killpg(proc.pid, signal.SIGUSR1)
time.sleep(3)

The sequence of events is

  1. The parent program instantiates Popen.
  2. The Popen instance forks a new process.
  3. The new process runs os.setpgrp().
  4. The new process runs exec() to start the shell.
  5. The shell runs the shell script.
  6. The shell script forks again and that process execs Python.
  7. Python runs signal_child.py.
  8. The parent program signals the process group using the pid of the shell.
  9. The shell and Python processes receive the signal.
  10. The shell ignores the signal.
  11. The Python process running signal_child.py invokes the signal handler.
$ python3 subprocess_signal_setpgrp.py

Calling os.setpgrp() from 75636
Process group is now 75636
PARENT      : Pausing before signaling 75636...
Shell script in process 75636
+ python3 signal_child.py
CHILD  75637: Setting up signal handler
CHILD  75637: Pausing to wait for signal
PARENT      : Signaling process group 75636
CHILD  75637: Received USR1

See also

  • Standard library documentation for subprocess
  • os – Although subprocess replaces many of them, the
    functions for working with processes found in the os
    module are still widely used in existing code.
  • UNIX Signals and Process Groups
    – A good description of Unix signaling and how process groups
    work.
  • signal – More details about using the signal module.
  • Advanced Programming in the UNIX(R) Environment
    – Covers working with multiple processes, such as handling
    signals, closing duplicated file descriptors, etc.
  • pipes – Unix shell command pipeline templates in the
    standard library.

Python 2.7.10

17.1. subprocess — Subprocess management

New in version 2.4.

The subprocess module allows you to spawn new processes, connect to their
input/output/error pipes, and obtain their return codes. This module intends to
replace several older modules and functions:

os.system
os.spawn*
os.popen*
popen2.*
commands.*

Information about how this module can be used to replace the older
functions can be found in the subprocess-replacements section.

See also

POSIX users (Linux, BSD, etc.) are strongly encouraged to install
and use the much more recent subprocess32 module instead of the
version included with python 2.7. It is a drop in replacement with
better behavior in many situations.

PEP 324 – PEP proposing the subprocess module

17.1.1. Using the subprocess Module

The recommended way to launch subprocesses is to use the following
convenience functions. For more advanced use cases when these do not
meet your needs, use the underlying Popen interface.

subprocess.call(args, *, stdin=None, stdout=None, stderr=None, shell=False)

Run the command described by args. Wait for command to complete, then
return the returncode attribute.

The arguments shown above are merely the most common ones, described below
in Frequently Used Arguments (hence the slightly odd notation in
the abbreviated signature). The full function signature is the same as
that of the Popen constructor — this functions passes all
supplied arguments directly through to that interface.

Examples:

>>> subprocess.call(["ls", "-l"])
0

>>> subprocess.call("exit 1", shell=True)
1

Warning

Using shell=True can be a security hazard. See the warning
under Frequently Used Arguments for details.

Note

Do not use stdout=PIPE or stderr=PIPE with this function
as that can deadlock based on the child process output volume.
Use Popen with the communicate() method when you
need pipes.

subprocess.check_call(args, *, stdin=None, stdout=None, stderr=None, shell=False)

Run command with arguments. Wait for command to complete. If the return
code was zero then return, otherwise raise CalledProcessError. The
CalledProcessError object will have the return code in the
returncode attribute.

The arguments shown above are merely the most common ones, described below
in Frequently Used Arguments (hence the slightly odd notation in
the abbreviated signature). The full function signature is the same as
that of the Popen constructor — this functions passes all
supplied arguments directly through to that interface.

Examples:

>>> subprocess.check_call(["ls", "-l"])
0

>>> subprocess.check_call("exit 1", shell=True)
Traceback (most recent call last):
   ...
subprocess.CalledProcessError: Command 'exit 1' returned non-zero exit status 1

New in version 2.5.

Warning

Using shell=True can be a security hazard. See the warning
under Frequently Used Arguments for details.

Note

Do not use stdout=PIPE or stderr=PIPE with this function
as that can deadlock based on the child process output volume.
Use Popen with the communicate() method when you
need pipes.

subprocess.check_output(args, *, stdin=None, stderr=None, shell=False, universal_newlines=False)

Run command with arguments and return its output as a byte string.

If the return code was non-zero it raises a CalledProcessError. The
CalledProcessError object will have the return code in the
returncode attribute and any output in the
output attribute.

The arguments shown above are merely the most common ones, described below
in Frequently Used Arguments (hence the slightly odd notation in
the abbreviated signature). The full function signature is largely the
same as that of the Popen constructor, except that stdout is
not permitted as it is used internally. All other supplied arguments are
passed directly through to the Popen constructor.

Examples:

>>> subprocess.check_output(["echo", "Hello World!"])
'Hello World!n'

>>> subprocess.check_output("exit 1", shell=True)
Traceback (most recent call last):
   ...
subprocess.CalledProcessError: Command 'exit 1' returned non-zero exit status 1

To also capture standard error in the result, use
stderr=subprocess.STDOUT:

>>> subprocess.check_output(
...     "ls non_existent_file; exit 0",
...     stderr=subprocess.STDOUT,
...     shell=True)
'ls: non_existent_file: No such file or directoryn'

New in version 2.7.

Warning

Using shell=True can be a security hazard. See the warning
under Frequently Used Arguments for details.

Note

Do not use stderr=PIPE with this function as that can deadlock
based on the child process error volume. Use Popen with
the communicate() method when you need a stderr pipe.

subprocess.PIPE

Special value that can be used as the stdin, stdout or stderr argument
to Popen and indicates that a pipe to the standard stream should be
opened.

subprocess.STDOUT

Special value that can be used as the stderr argument to Popen and
indicates that standard error should go into the same handle as standard
output.

exception subprocess.CalledProcessError

Exception raised when a process run by check_call() or
check_output() returns a non-zero exit status.

returncode

Exit status of the child process.

cmd

Command that was used to spawn the child process.

output

Output of the child process if this exception is raised by
check_output(). Otherwise, None.

17.1.1.1. Frequently Used Arguments

To support a wide variety of use cases, the Popen constructor (and
the convenience functions) accept a large number of optional arguments. For
most typical use cases, many of these arguments can be safely left at their
default values. The arguments that are most commonly needed are:

args is required for all calls and should be a string, or a sequence of
program arguments. Providing a sequence of arguments is generally
preferred, as it allows the module to take care of any required escaping
and quoting of arguments (e.g. to permit spaces in file names). If passing
a single string, either shell must be True (see below) or else
the string must simply name the program to be executed without specifying
any arguments.

stdin, stdout and stderr specify the executed program’s standard input,
standard output and standard error file handles, respectively. Valid values
are PIPE, an existing file descriptor (a positive integer), an
existing file object, and None. PIPE indicates that a new pipe
to the child should be created. With the default settings of None, no
redirection will occur; the child’s file handles will be inherited from the
parent. Additionally, stderr can be STDOUT, which indicates that
the stderr data from the child process should be captured into the same file
handle as for stdout.

When stdout or stderr are pipes and universal_newlines is
True then all line endings will be converted to ‘n’ as described
for the universal newlines ‘U’ mode argument to open().

If shell is True, the specified command will be executed through
the shell. This can be useful if you are using Python primarily for the
enhanced control flow it offers over most system shells and still want
convenient access to other shell features such as shell pipes, filename
wildcards, environment variable expansion, and expansion of ~ to a
user’s home directory. However, note that Python itself offers
implementations of many shell-like features (in particular, glob,
fnmatch, os.walk(), os.path.expandvars(),
os.path.expanduser(), and shutil).

Warning

Executing shell commands that incorporate unsanitized input from an
untrusted source makes a program vulnerable to shell injection,
a serious security flaw which can result in arbitrary command execution.
For this reason, the use of shell=True is strongly discouraged
in cases where the command string is constructed from external input:

>>> from subprocess import call
>>> filename = input("What file would you like to display?n")
What file would you like to display?
non_existent; rm -rf / #
>>> call("cat " + filename, shell=True) # Uh-oh. This will end badly...

shell=False disables all shell based features, but does not suffer
from this vulnerability; see the Note in the Popen constructor
documentation for helpful hints in getting shell=False to work.

When using shell=True, pipes.quote() can be used to properly
escape whitespace and shell metacharacters in strings that are going to
be used to construct shell commands.

These options, along with all of the other options, are described in more
detail in the Popen constructor documentation.

17.1.1.2. Popen Constructor

The underlying process creation and management in this module is handled by
the Popen class. It offers a lot of flexibility so that developers
are able to handle the less common cases not covered by the convenience
functions.

class subprocess.Popen(args, bufsize=0, executable=None, stdin=None, stdout=None, stderr=None, preexec_fn=None, close_fds=False, shell=False, cwd=None, env=None, universal_newlines=False, startupinfo=None, creationflags=0)

Execute a child program in a new process. On Unix, the class uses
os.execvp()-like behavior to execute the child program. On Windows,
the class uses the Windows CreateProcess() function. The arguments to
Popen are as follows.

args should be a sequence of program arguments or else a single string.
By default, the program to execute is the first item in args if args is
a sequence. If args is a string, the interpretation is
platform-dependent and described below. See the shell and executable
arguments for additional differences from the default behavior. Unless
otherwise stated, it is recommended to pass args as a sequence.

On Unix, if args is a string, the string is interpreted as the name or
path of the program to execute. However, this can only be done if not
passing arguments to the program.

Note

shlex.split() can be useful when determining the correct
tokenization for args, especially in complex cases:

>>> import shlex, subprocess
>>> command_line = raw_input()
/bin/vikings -input eggs.txt -output "spam spam.txt" -cmd "echo '$MONEY'"
>>> args = shlex.split(command_line)
>>> print args
['/bin/vikings', '-input', 'eggs.txt', '-output', 'spam spam.txt', '-cmd', "echo '$MONEY'"]
>>> p = subprocess.Popen(args) # Success!

Note in particular that options (such as -input) and arguments (such
as eggs.txt) that are separated by whitespace in the shell go in separate
list elements, while arguments that need quoting or backslash escaping when
used in the shell (such as filenames containing spaces or the echo command
shown above) are single list elements.

On Windows, if args is a sequence, it will be converted to a string in a
manner described in Converting an argument sequence to a string on Windows. This is because
the underlying CreateProcess() operates on strings.

The shell argument (which defaults to False) specifies whether to use
the shell as the program to execute. If shell is True, it is
recommended to pass args as a string rather than as a sequence.

On Unix with shell=True, the shell defaults to /bin/sh. If
args is a string, the string specifies the command
to execute through the shell. This means that the string must be
formatted exactly as it would be when typed at the shell prompt. This
includes, for example, quoting or backslash escaping filenames with spaces in
them. If args is a sequence, the first item specifies the command string, and
any additional items will be treated as additional arguments to the shell
itself. That is to say, Popen does the equivalent of:

Popen(['/bin/sh', '-c', args[0], args[1], ...])

On Windows with shell=True, the COMSPEC environment variable
specifies the default shell. The only time you need to specify
shell=True on Windows is when the command you wish to execute is built
into the shell (e.g. dir or copy). You do not need
shell=True to run a batch file or console-based executable.

Warning

Passing shell=True can be a security hazard if combined with
untrusted input. See the warning under Frequently Used Arguments
for details.

bufsize, if given, has the same meaning as the corresponding argument to the
built-in open() function: 0 means unbuffered, 1 means line
buffered, any other positive value means use a buffer of (approximately) that
size. A negative bufsize means to use the system default, which usually means
fully buffered. The default value for bufsize is 0 (unbuffered).

Note

If you experience performance issues, it is recommended that you try to
enable buffering by setting bufsize to either -1 or a large enough
positive value (such as 4096).

The executable argument specifies a replacement program to execute. It
is very seldom needed. When shell=False, executable replaces the
program to execute specified by args. However, the original args is
still passed to the program. Most programs treat the program specified
by args as the command name, which can then be different from the program
actually executed. On Unix, the args name
becomes the display name for the executable in utilities such as
ps. If shell=True, on Unix the executable argument
specifies a replacement shell for the default /bin/sh.

stdin, stdout and stderr specify the executed program’s standard input,
standard output and standard error file handles, respectively. Valid values
are PIPE, an existing file descriptor (a positive integer), an
existing file object, and None. PIPE indicates that a new pipe
to the child should be created. With the default settings of None, no
redirection will occur; the child’s file handles will be inherited from the
parent. Additionally, stderr can be STDOUT, which indicates that
the stderr data from the child process should be captured into the same file
handle as for stdout.

If preexec_fn is set to a callable object, this object will be called in the
child process just before the child is executed. (Unix only)

If close_fds is true, all file descriptors except 0, 1 and
2 will be closed before the child process is executed. (Unix only).
Or, on Windows, if close_fds is true then no handles will be inherited by the
child process. Note that on Windows, you cannot set close_fds to true and
also redirect the standard handles by setting stdin, stdout or stderr.

If cwd is not None, the child’s current directory will be changed to cwd
before it is executed. Note that this directory is not considered when
searching the executable, so you can’t specify the program’s path relative to
cwd.

If env is not None, it must be a mapping that defines the environment
variables for the new process; these are used instead of inheriting the current
process’ environment, which is the default behavior.

Note

If specified, env must provide any variables required
for the program to execute. On Windows, in order to run a
side-by-side assembly the specified env must include a valid
SystemRoot.

If universal_newlines is True, the file objects stdout and stderr
are opened as text files in universal newlines mode. Lines may be
terminated by any of ‘n’, the Unix end-of-line convention, ‘r’,
the old Macintosh convention or ‘rn’, the Windows convention. All of
these external representations are seen as ‘n’ by the Python program.

Note

This feature is only available if Python is built with universal newline
support (the default). Also, the newlines attribute of the file objects
stdout, stdin and stderr are not updated by the
communicate() method.

If given, startupinfo will be a STARTUPINFO object, which is
passed to the underlying CreateProcess function.
creationflags, if given, can be CREATE_NEW_CONSOLE or
CREATE_NEW_PROCESS_GROUP. (Windows only)

17.1.1.3. Exceptions

Exceptions raised in the child process, before the new program has started to
execute, will be re-raised in the parent. Additionally, the exception object
will have one extra attribute called child_traceback, which is a string
containing traceback information from the child’s point of view.

The most common exception raised is OSError. This occurs, for example,
when trying to execute a non-existent file. Applications should prepare for
OSError exceptions.

A ValueError will be raised if Popen is called with invalid
arguments.

check_call() and check_output() will raise
CalledProcessError if the called process returns a non-zero return
code.

17.1.1.4. Security

Unlike some other popen functions, this implementation will never call a
system shell implicitly. This means that all characters, including shell
metacharacters, can safely be passed to child processes. Obviously, if the
shell is invoked explicitly, then it is the application’s responsibility to
ensure that all whitespace and metacharacters are quoted appropriately.

17.1.2. Popen Objects

Instances of the Popen class have the following methods:

Popen.poll()

Check if child process has terminated. Set and return
returncode attribute.

Popen.wait()

Wait for child process to terminate. Set and return
returncode attribute.

Warning

This will deadlock when using stdout=PIPE and/or
stderr=PIPE and the child process generates enough output to
a pipe such that it blocks waiting for the OS pipe buffer to
accept more data. Use communicate() to avoid that.

Popen.communicate(input=None)

Interact with process: Send data to stdin. Read data from stdout and stderr,
until end-of-file is reached. Wait for process to terminate. The optional
input argument should be a string to be sent to the child process, or
None, if no data should be sent to the child.

communicate() returns a tuple (stdoutdata, stderrdata).

Note that if you want to send data to the process’s stdin, you need to create
the Popen object with stdin=PIPE. Similarly, to get anything other than
None in the result tuple, you need to give stdout=PIPE and/or
stderr=PIPE too.

Note

The data read is buffered in memory, so do not use this method if the data
size is large or unlimited.

Popen.send_signal(signal)

Sends the signal signal to the child.

Note

On Windows, SIGTERM is an alias for terminate(). CTRL_C_EVENT and
CTRL_BREAK_EVENT can be sent to processes started with a creationflags
parameter which includes CREATE_NEW_PROCESS_GROUP.

New in version 2.6.

Popen.terminate()

Stop the child. On Posix OSs the method sends SIGTERM to the
child. On Windows the Win32 API function TerminateProcess() is called
to stop the child.

New in version 2.6.

Popen.kill()

Kills the child. On Posix OSs the function sends SIGKILL to the child.
On Windows kill() is an alias for terminate().

New in version 2.6.

The following attributes are also available:

Warning

Use communicate() rather than .stdin.write,
.stdout.read or .stderr.read to avoid
deadlocks due to any of the other OS pipe buffers filling up and blocking the
child process.

Popen.stdin

If the stdin argument was PIPE, this attribute is a file object
that provides input to the child process. Otherwise, it is None.

Popen.stdout

If the stdout argument was PIPE, this attribute is a file object
that provides output from the child process. Otherwise, it is None.

Popen.stderr

If the stderr argument was PIPE, this attribute is a file object
that provides error output from the child process. Otherwise, it is
None.

Popen.pid

The process ID of the child process.

Note that if you set the shell argument to True, this is the process ID
of the spawned shell.

Popen.returncode

The child return code, set by poll() and wait() (and indirectly
by communicate()). A None value indicates that the process
hasn’t terminated yet.

A negative value -N indicates that the child was terminated by signal
N (Unix only).

17.1.3. Windows Popen Helpers

The STARTUPINFO class and following constants are only available
on Windows.

class subprocess.STARTUPINFO

Partial support of the Windows
STARTUPINFO
structure is used for Popen creation.

dwFlags

A bit field that determines whether certain STARTUPINFO
attributes are used when the process creates a window.

si = subprocess.STARTUPINFO()
si.dwFlags = subprocess.STARTF_USESTDHANDLES | subprocess.STARTF_USESHOWWINDOW
hStdInput

If dwFlags specifies STARTF_USESTDHANDLES, this attribute
is the standard input handle for the process. If
STARTF_USESTDHANDLES is not specified, the default for standard
input is the keyboard buffer.

hStdOutput

If dwFlags specifies STARTF_USESTDHANDLES, this attribute
is the standard output handle for the process. Otherwise, this attribute
is ignored and the default for standard output is the console window’s
buffer.

hStdError

If dwFlags specifies STARTF_USESTDHANDLES, this attribute
is the standard error handle for the process. Otherwise, this attribute is
ignored and the default for standard error is the console window’s buffer.

wShowWindow

If dwFlags specifies STARTF_USESHOWWINDOW, this attribute
can be any of the values that can be specified in the nCmdShow
parameter for the
ShowWindow
function, except for SW_SHOWDEFAULT. Otherwise, this attribute is
ignored.

SW_HIDE is provided for this attribute. It is used when
Popen is called with shell=True.

17.1.3.1. Constants

The subprocess module exposes the following constants.

subprocess.STD_INPUT_HANDLE

The standard input device. Initially, this is the console input buffer,
CONIN$.

subprocess.STD_OUTPUT_HANDLE

The standard output device. Initially, this is the active console screen
buffer, CONOUT$.

subprocess.STD_ERROR_HANDLE

The standard error device. Initially, this is the active console screen
buffer, CONOUT$.

subprocess.SW_HIDE

Hides the window. Another window will be activated.

subprocess.STARTF_USESTDHANDLES

Specifies that the STARTUPINFO.hStdInput,
STARTUPINFO.hStdOutput, and STARTUPINFO.hStdError attributes
contain additional information.

subprocess.STARTF_USESHOWWINDOW

Specifies that the STARTUPINFO.wShowWindow attribute contains
additional information.

subprocess.CREATE_NEW_CONSOLE

The new process has a new console, instead of inheriting its parent’s
console (the default).

This flag is always set when Popen is created with shell=True.

subprocess.CREATE_NEW_PROCESS_GROUP

A Popen creationflags parameter to specify that a new process
group will be created. This flag is necessary for using os.kill()
on the subprocess.

This flag is ignored if CREATE_NEW_CONSOLE is specified.

17.1.4. Replacing Older Functions with the subprocess Module

In this section, “a becomes b” means that b can be used as a replacement for a.

Note

All “a” functions in this section fail (more or less) silently if the
executed program cannot be found; the “b” replacements raise OSError
instead.

In addition, the replacements using check_output() will fail with a
CalledProcessError if the requested operation produces a non-zero
return code. The output is still available as the
output attribute of the raised exception.

In the following examples, we assume that the relevant functions have already
been imported from the subprocess module.

17.1.4.1. Replacing /bin/sh shell backquote

output=`mycmd myarg`
# becomes
output = check_output(["mycmd", "myarg"])

17.1.4.2. Replacing shell pipeline

output=`dmesg | grep hda`
# becomes
p1 = Popen(["dmesg"], stdout=PIPE)
p2 = Popen(["grep", "hda"], stdin=p1.stdout, stdout=PIPE)
p1.stdout.close()  # Allow p1 to receive a SIGPIPE if p2 exits.
output = p2.communicate()[0]

The p1.stdout.close() call after starting the p2 is important in order for p1
to receive a SIGPIPE if p2 exits before p1.

Alternatively, for trusted input, the shell’s own pipeline support may still
be used directly:

output=`dmesg | grep hda`
# becomes
output=check_output("dmesg | grep hda", shell=True)

17.1.4.3. Replacing os.system()

status = os.system("mycmd" + " myarg")
# becomes
status = subprocess.call("mycmd" + " myarg", shell=True)

Notes:

  • Calling the program through the shell is usually not required.

A more realistic example would look like this:

try:
    retcode = call("mycmd" + " myarg", shell=True)
    if retcode < 0:
        print >>sys.stderr, "Child was terminated by signal", -retcode
    else:
        print >>sys.stderr, "Child returned", retcode
except OSError as e:
    print >>sys.stderr, "Execution failed:", e

17.1.4.4. Replacing the os.spawn family

P_NOWAIT example:

pid = os.spawnlp(os.P_NOWAIT, "/bin/mycmd", "mycmd", "myarg")
==>
pid = Popen(["/bin/mycmd", "myarg"]).pid

P_WAIT example:

retcode = os.spawnlp(os.P_WAIT, "/bin/mycmd", "mycmd", "myarg")
==>
retcode = call(["/bin/mycmd", "myarg"])

Vector example:

os.spawnvp(os.P_NOWAIT, path, args)
==>
Popen([path] + args[1:])

Environment example:

os.spawnlpe(os.P_NOWAIT, "/bin/mycmd", "mycmd", "myarg", env)
==>
Popen(["/bin/mycmd", "myarg"], env={"PATH": "/usr/bin"})

17.1.4.5. Replacing os.popen(), os.popen2(), os.popen3()

pipe = os.popen("cmd", 'r', bufsize)
==>
pipe = Popen("cmd", shell=True, bufsize=bufsize, stdout=PIPE).stdout
pipe = os.popen("cmd", 'w', bufsize)
==>
pipe = Popen("cmd", shell=True, bufsize=bufsize, stdin=PIPE).stdin
(child_stdin, child_stdout) = os.popen2("cmd", mode, bufsize)
==>
p = Popen("cmd", shell=True, bufsize=bufsize,
          stdin=PIPE, stdout=PIPE, close_fds=True)
(child_stdin, child_stdout) = (p.stdin, p.stdout)
(child_stdin,
 child_stdout,
 child_stderr) = os.popen3("cmd", mode, bufsize)
==>
p = Popen("cmd", shell=True, bufsize=bufsize,
          stdin=PIPE, stdout=PIPE, stderr=PIPE, close_fds=True)
(child_stdin,
 child_stdout,
 child_stderr) = (p.stdin, p.stdout, p.stderr)
(child_stdin, child_stdout_and_stderr) = os.popen4("cmd", mode,
                                                   bufsize)
==>
p = Popen("cmd", shell=True, bufsize=bufsize,
          stdin=PIPE, stdout=PIPE, stderr=STDOUT, close_fds=True)
(child_stdin, child_stdout_and_stderr) = (p.stdin, p.stdout)

On Unix, os.popen2, os.popen3 and os.popen4 also accept a sequence as
the command to execute, in which case arguments will be passed
directly to the program without shell intervention. This usage can be
replaced as follows:

(child_stdin, child_stdout) = os.popen2(["/bin/ls", "-l"], mode,
                                        bufsize)
==>
p = Popen(["/bin/ls", "-l"], bufsize=bufsize, stdin=PIPE, stdout=PIPE)
(child_stdin, child_stdout) = (p.stdin, p.stdout)

Return code handling translates as follows:

pipe = os.popen("cmd", 'w')
...
rc = pipe.close()
if rc is not None and rc >> 8:
    print "There were some errors"
==>
process = Popen("cmd", 'w', shell=True, stdin=PIPE)
...
process.stdin.close()
if process.wait() != 0:
    print "There were some errors"

17.1.4.6. Replacing functions from the popen2 module

(child_stdout, child_stdin) = popen2.popen2("somestring", bufsize, mode)
==>
p = Popen("somestring", shell=True, bufsize=bufsize,
          stdin=PIPE, stdout=PIPE, close_fds=True)
(child_stdout, child_stdin) = (p.stdout, p.stdin)

On Unix, popen2 also accepts a sequence as the command to execute, in
which case arguments will be passed directly to the program without
shell intervention. This usage can be replaced as follows:

(child_stdout, child_stdin) = popen2.popen2(["mycmd", "myarg"], bufsize,
                                            mode)
==>
p = Popen(["mycmd", "myarg"], bufsize=bufsize,
          stdin=PIPE, stdout=PIPE, close_fds=True)
(child_stdout, child_stdin) = (p.stdout, p.stdin)

popen2.Popen3 and popen2.Popen4 basically work as
subprocess.Popen, except that:

  • Popen raises an exception if the execution fails.
  • the capturestderr argument is replaced with the stderr argument.
  • stdin=PIPE and stdout=PIPE must be specified.
  • popen2 closes all file descriptors by default, but you have to specify
    close_fds=True with Popen.

17.1.5. Notes

17.1.5.1. Converting an argument sequence to a string on Windows

On Windows, an args sequence is converted to a string that can be parsed
using the following rules (which correspond to the rules used by the MS C
runtime):

  1. Arguments are delimited by white space, which is either a
    space or a tab.
  2. A string surrounded by double quotation marks is
    interpreted as a single argument, regardless of white space
    contained within. A quoted string can be embedded in an
    argument.
  3. A double quotation mark preceded by a backslash is
    interpreted as a literal double quotation mark.
  4. Backslashes are interpreted literally, unless they
    immediately precede a double quotation mark.
  5. If backslashes immediately precede a double quotation mark,
    every pair of backslashes is interpreted as a literal
    backslash. If the number of backslashes is odd, the last
    backslash escapes the next double quotation mark as
    described in rule 3.

Понравилась статья? Поделить с друзьями:
  • Python solver error
  • Python socket timeout error
  • Python socket error eof
  • Python socket error class
  • Python socket connection error