.. currentmodule:: asyncio

.. _asyncio-subprocess:

============
Subprocesses
============

**Source code:** :source:`Lib/asyncio/subprocess.py`,
:source:`Lib/asyncio/base_subprocess.py`

----------------------------------------

This section describes high-level async/await asyncio APIs to
create and manage subprocesses.

.. _asyncio_example_subprocess_shell:

Here's an example of how asyncio can run a shell command and
obtain its result::

    import asyncio

    async def run(cmd):
        proc = await asyncio.create_subprocess_shell(
            cmd,
            stdout=asyncio.subprocess.PIPE,
            stderr=asyncio.subprocess.PIPE)

        stdout, stderr = await proc.communicate()

        print(f'[{cmd!r} exited with {proc.returncode}]')
        if stdout:
            print(f'[stdout]\n{stdout.decode()}')
        if stderr:
            print(f'[stderr]\n{stderr.decode()}')

    asyncio.run(run('ls /zzz'))

will print::

    ['ls /zzz' exited with 1]
    [stderr]
    ls: /zzz: No such file or directory

Because all asyncio subprocess functions are asynchronous and asyncio
provides many tools to work with such functions, it is easy to execute
and monitor multiple subprocesses in parallel.  It is indeed trivial
to modify the above example to run several commands simultaneously::

    async def main():
        await asyncio.gather(
            run('ls /zzz'),
            run('sleep 1; echo "hello"'))

    asyncio.run(main())

See also the `Examples`_ subsection.


Creating Subprocesses
=====================

.. function:: create_subprocess_exec(program, *args, stdin=None, \
                 stdout=None, stderr=None, limit=None, **kwds)
   :async:

   Create a subprocess.

   The *limit* argument sets the buffer limit for :class:`StreamReader`
   wrappers for :attr:`~asyncio.subprocess.Process.stdout` and :attr:`~asyncio.subprocess.Process.stderr`
   (if :const:`subprocess.PIPE` is passed to *stdout* and *stderr* arguments).

   Return a :class:`~asyncio.subprocess.Process` instance.

   See the documentation of :meth:`loop.subprocess_exec` for other
   parameters.

   If the process object is garbage collected while the process is still
   running, the child process will be killed.

   .. versionchanged:: 3.10
      Removed the *loop* parameter.


.. function:: create_subprocess_shell(cmd, stdin=None, \
                 stdout=None, stderr=None, limit=None, **kwds)
   :async:

   Run the *cmd* shell command.

   The *limit* argument sets the buffer limit for :class:`StreamReader`
   wrappers for :attr:`~asyncio.subprocess.Process.stdout` and :attr:`~asyncio.subprocess.Process.stderr`
   (if :const:`subprocess.PIPE` is passed to *stdout* and *stderr* arguments).

   Return a :class:`~asyncio.subprocess.Process` instance.

   See the documentation of :meth:`loop.subprocess_shell` for other
   parameters.

   If the process object is garbage collected while the process is still
   running, the child process will be killed.

   .. important::

      It is the application's responsibility to ensure that all whitespace and
      special characters are quoted appropriately to avoid `shell injection
      <https://en.wikipedia.org/wiki/Shell_injection#Shell_injection>`_
      vulnerabilities. The :func:`shlex.quote` function can be used to properly
      escape whitespace and special shell characters in strings that are going
      to be used to construct shell commands.

   .. versionchanged:: 3.10
      Removed the *loop* parameter.

.. note::

   Subprocesses are available for Windows if a :class:`ProactorEventLoop` is
   used. See :ref:`Subprocess Support on Windows <asyncio-windows-subprocess>`
   for details.

.. seealso::

   asyncio also has the following *low-level* APIs to work with subprocesses:
   :meth:`loop.subprocess_exec`, :meth:`loop.subprocess_shell`,
   :meth:`loop.connect_read_pipe`, :meth:`loop.connect_write_pipe`,
   as well as the :ref:`Subprocess Transports <asyncio-subprocess-transports>`
   and :ref:`Subprocess Protocols <asyncio-subprocess-protocols>`.


Constants
=========

.. data:: asyncio.subprocess.PIPE
   :module:

   Can be passed to the *stdin*, *stdout* or *stderr* parameters.

   If *PIPE* is passed to *stdin* argument, the
   :attr:`Process.stdin <asyncio.subprocess.Process.stdin>` attribute
   will point to a :class:`~asyncio.StreamWriter` instance.

   If *PIPE* is passed to *stdout* or *stderr* arguments, the
   :attr:`Process.stdout <asyncio.subprocess.Process.stdout>` and
   :attr:`Process.stderr <asyncio.subprocess.Process.stderr>`
   attributes will point to :class:`~asyncio.StreamReader` instances.

.. data:: asyncio.subprocess.STDOUT
   :module:

   Special value that can be used as the *stderr* argument and indicates
   that standard error should be redirected into standard output.

.. data:: asyncio.subprocess.DEVNULL
   :module:

   Special value that can be used as the *stdin*, *stdout* or *stderr* argument
   to process creation functions.  It indicates that the special file
   :data:`os.devnull` will be used for the corresponding subprocess stream.


Interacting with Subprocesses
=============================

Both :func:`create_subprocess_exec` and :func:`create_subprocess_shell`
functions return instances of the *Process* class.  *Process* is a high-level
wrapper that allows communicating with subprocesses and watching for
their completion.

.. class:: asyncio.subprocess.Process
   :module:

   An object that wraps OS processes created by the
   :func:`~asyncio.create_subprocess_exec` and :func:`~asyncio.create_subprocess_shell`
   functions.

   This class is designed to have a similar API to the
   :class:`subprocess.Popen` class, but there are some
   notable differences:

   * unlike Popen, Process instances do not have an equivalent to
     the :meth:`~subprocess.Popen.poll` method;

   * the :meth:`~asyncio.subprocess.Process.communicate` and
     :meth:`~asyncio.subprocess.Process.wait` methods don't have a
     *timeout* parameter: use the :func:`~asyncio.wait_for` function;

   * the :meth:`Process.wait() <asyncio.subprocess.Process.wait>` method
     is asynchronous, whereas :meth:`subprocess.Popen.wait` method
     is implemented as a blocking busy loop;

   * the *universal_newlines* parameter is not supported.

   This class is :ref:`not thread safe <asyncio-multithreading>`.

   See also the :ref:`Subprocess and Threads <asyncio-subprocess-threads>`
   section.

   .. method:: wait()
      :async:

      Wait for the child process to terminate.

      Set and return the :attr:`returncode` attribute.

      .. note::

         This method can deadlock when using ``stdout=PIPE`` or
         ``stderr=PIPE`` and the child process generates so much output
         that it blocks waiting for the OS pipe buffer to accept
         more data. Use the :meth:`communicate` method when using pipes
         to avoid this condition.

   .. method:: communicate(input=None)
      :async:

      Interact with process:

      1. send data to *stdin* (if *input* is not ``None``);
      2. closes *stdin*;
      3. read data from *stdout* and *stderr*, until EOF is reached;
      4. wait for process to terminate.

      The optional *input* argument is the data (:class:`bytes` object)
      that will be sent to the child process.

      Return a tuple ``(stdout_data, stderr_data)``.

      If either :exc:`BrokenPipeError` or :exc:`ConnectionResetError`
      exception is raised when writing *input* into *stdin*, the
      exception is ignored.  This condition occurs when the process
      exits before all data are written into *stdin*.

      If it is desired to send data to the process' *stdin*,
      the process needs to be created with ``stdin=PIPE``.  Similarly,
      to get anything other than ``None`` in the result tuple, the
      process has to be created with ``stdout=PIPE`` and/or
      ``stderr=PIPE`` arguments.

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

      .. versionchanged:: 3.12

         *stdin* gets closed when ``input=None`` too.

   .. method:: send_signal(signal)

      Sends the signal *signal* to the child process.

      .. note::

         On Windows, :py:const:`~signal.SIGTERM` is an alias for :meth:`terminate`.
         ``CTRL_C_EVENT`` and ``CTRL_BREAK_EVENT`` can be sent to processes
         started with a *creationflags* parameter which includes
         ``CREATE_NEW_PROCESS_GROUP``.

   .. method:: terminate()

      Stop the child process.

      On POSIX systems this method sends :py:const:`~signal.SIGTERM` to the
      child process.

      On Windows the Win32 API function :c:func:`!TerminateProcess` is
      called to stop the child process.

   .. method:: kill()

      Kill the child process.

      On POSIX systems this method sends :py:data:`~signal.SIGKILL` to the child
      process.

      On Windows this method is an alias for :meth:`terminate`.

   .. attribute:: stdin

      Standard input stream (:class:`~asyncio.StreamWriter`) or ``None``
      if the process was created with ``stdin=None``.

   .. attribute:: stdout

      Standard output stream (:class:`~asyncio.StreamReader`) or ``None``
      if the process was created with ``stdout=None``.

   .. attribute:: stderr

      Standard error stream (:class:`~asyncio.StreamReader`) or ``None``
      if the process was created with ``stderr=None``.

   .. warning::

      Use the :meth:`communicate` method rather than
      :attr:`process.stdin.write() <stdin>`,
      :attr:`await process.stdout.read() <stdout>` or
      :attr:`await process.stderr.read() <stderr>`.
      This avoids deadlocks due to streams pausing reading or writing
      and blocking the child process.

   .. attribute:: pid

      Process identification number (PID).

      Note that for processes created by the :func:`~asyncio.create_subprocess_shell`
      function, this attribute is the PID of the spawned shell.

   .. attribute:: returncode

      Return code of the process when it exits.

      A ``None`` value indicates that the process has not terminated yet.

      For processes created with :func:`~asyncio.create_subprocess_exec`, a negative
      value ``-N`` indicates that the child was terminated by signal ``N``
      (POSIX only).

      For processes created with :func:`~asyncio.create_subprocess_shell`, the
      return code reflects the exit status of the shell itself (e.g. ``/bin/sh``),
      which may map signals to codes such as ``128+N``. See the
      documentation of the shell (for example, the Bash manual's Exit Status)
      for details.



.. _asyncio-subprocess-threads:

Subprocess and Threads
----------------------

Standard asyncio event loop supports running subprocesses from different threads by
default.

On Windows subprocesses are provided by :class:`ProactorEventLoop` only (default),
:class:`SelectorEventLoop` has no subprocess support.

Note that alternative event loop implementations might have own limitations;
please refer to their documentation.

.. seealso::

   The :ref:`Concurrency and multithreading in asyncio
   <asyncio-multithreading>` section.


Examples
--------

An example using the :class:`~asyncio.subprocess.Process` class to
control a subprocess and the :class:`StreamReader` class to read from
its standard output.

.. _asyncio_example_create_subprocess_exec:

The subprocess is created by the :func:`create_subprocess_exec`
function::

    import asyncio
    import sys

    async def get_date():
        code = 'import datetime as dt; print(dt.datetime.now())'

        # Create the subprocess; redirect the standard output
        # into a pipe.
        proc = await asyncio.create_subprocess_exec(
            sys.executable, '-c', code,
            stdout=asyncio.subprocess.PIPE)

        # Read one line of output.
        data = await proc.stdout.readline()
        line = data.decode('ascii').rstrip()

        # Wait for the subprocess exit.
        await proc.wait()
        return line

    date = asyncio.run(get_date())
    print(f"Current date: {date}")


See also the :ref:`same example <asyncio_example_subprocess_proto>`
written using low-level APIs.
