# 7 PEP 324: New subprocess Module

The standard library provides a number of ways to execute a subprocess, offering different features and different levels of complexity. `os.system(command)` is easy to use, but slow (it runs a shell process which executes the command) and dangerous (you have to be careful about escaping the shell's metacharacters). The `popen2` module offers classes that can capture standard output and standard error from the subprocess, but the naming is confusing. The `subprocess` module cleans this up, providing a unified interface that offers all the features you might need.

Instead of `popen2`'s collection of classes, `subprocess` contains a single class called `Popen` whose constructor supports a number of different keyword arguments.

    class 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):

args is commonly a sequence of strings that will be the arguments to the program executed as the subprocess. (If the shell argument is true, args can be a string which will then be passed on to the shell for interpretation, just as `os.system()` does.)

stdin, stdout, and stderr specify what the subprocess's input, output, and error streams will be. You can provide a file object or a file descriptor, or you can use the constant `subprocess.PIPE` to create a pipe between the subprocess and the parent.

The constructor has a number of handy options:

- close_fds requests that all file descriptors be closed before running the subprocess.

- cwd specifies the working directory in which the subprocess will be executed (defaulting to whatever the parent's working directory is).

- env is a dictionary specifying environment variables.

- preexec_fn is a function that gets called before the child is started.

- universal_newlines opens the child's input and output using Python's universal newline feature.

Once you've created the `Popen` instance, you can call its `wait()` method to pause until the subprocess has exited, `poll()` to check if it's exited without pausing, or `communicate(data)` to send the string data to the subprocess's standard input. `communicate(data)` then reads any data that the subprocess has sent to its standard output or standard error, returning a tuple `(stdout_data, stderr_data)`.

`call()` is a shortcut that passes its arguments along to the `Popen` constructor, waits for the command to complete, and returns the status code of the subprocess. It can serve as a safer analog to `os.system()`:

    sts = subprocess.call(['dpkg', '-i', '/tmp/new-package.deb'])
    if sts == 0:
        # Success
        ...
    else:
        # dpkg returned an error
        ...

The command is invoked without use of the shell. If you really do want to use the shell, you can add `shell=True` as a keyword argument and provide a string instead of a sequence:

    sts = subprocess.call('dpkg -i /tmp/new-package.deb', shell=True)

The PEP takes various examples of shell and Python code and shows how they'd be translated into Python code that uses `subprocess`. Reading this section of the PEP is highly recommended.

See Also:

PEP 324, subprocess - New process module
  Written and implemented by Peter Åstrand, with assistance from Fredrik Lundh and others.