| .. 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=65536, **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=65536, **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. | |
| If this coroutine is cancelled (for example, when a timeout is | |
| set with :func:`~asyncio.wait_for`), the output that was already | |
| read is not lost: call :meth:`!communicate` again to read the | |
| remaining output and get the complete data:: | |
| try: | |
| stdout, stderr = await asyncio.wait_for( | |
| proc.communicate(), timeout=5.0) | |
| except TimeoutError: | |
| proc.kill() | |
| stdout, stderr = await proc.communicate() | |
| Passing *input* after a previous :meth:`!communicate` call was | |
| cancelled raises :exc:`ValueError`; pass ``input=None`` to | |
| continue the communication, the original *input* is used. | |
| .. versionchanged:: 3.12 | |
| *stdin* gets closed when ``input=None`` too. | |
| .. versionchanged:: next | |
| If :meth:`!communicate` is cancelled, the output that was | |
| already read is now preserved and returned by a subsequent | |
| :meth:`!communicate` call. Passing *input* to a | |
| :meth:`!communicate` call following a cancelled one now raises | |
| :exc:`ValueError`. | |
| .. 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. |