| .. currentmodule:: asyncio |
| |
| .. _asyncio-subprocess: |
| |
| ============ |
| Subprocesses |
| ============ |
| |
| 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 |
| ===================== |
| |
| .. coroutinefunction:: create_subprocess_exec(\*args, stdin=None, \ |
| stdout=None, stderr=None, loop=None, \ |
| limit=None, \*\*kwds) |
| |
| Create a subprocess. |
| |
| The *limit* argument sets the buffer limit for :class:`StreamReader` |
| wrappers for :attr:`Process.stdout` and :attr:`Process.stderr` |
| (if :attr:`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. |
| |
| .. coroutinefunction:: create_subprocess_shell(cmd, stdin=None, \ |
| stdout=None, stderr=None, loop=None, \ |
| limit=None, \*\*kwds) |
| |
| Run the *cmd* shell command. |
| |
| The *limit* argument sets the buffer limit for :class:`StreamReader` |
| wrappers for :attr:`Process.stdout` and :attr:`Process.stderr` |
| (if :attr:`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. |
| |
| .. 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. |
| |
| .. note:: |
| |
| The default asyncio event loop implementation on **Windows** does not |
| support subprocesses. 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 |
| |
| 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:`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:`StreamReader` instances. |
| |
| .. data:: asyncio.subprocess.STDOUT |
| |
| 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 |
| |
| 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 |
| |
| An object that wraps OS processes created by the |
| :func:`create_subprocess_exec` and :func:`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:`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. |
| |
| .. coroutinemethod:: wait() |
| |
| 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. |
| |
| .. coroutinemethod:: communicate(input=None) |
| |
| Interact with process: |
| |
| 1. send data to *stdin* (if *input* is not ``None``); |
| 2. read data from *stdout* and *stderr*, until EOF is reached; |
| 3. 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. |
| |
| .. method:: send_signal(signal) |
| |
| Sends the signal *signal* to the child process. |
| |
| .. note:: |
| |
| On Windows, :py:data:`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:data:`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. |
| |
| On POSIX systems this method sends :py:data:`SIGKILL` to the child |
| process. |
| |
| On Windows this method is an alias for :meth:`terminate`. |
| |
| .. attribute:: stdin |
| |
| Standard input stream (:class:`StreamWriter`) or ``None`` |
| if the process was created with ``stdin=None``. |
| |
| .. attribute:: stdout |
| |
| Standard output stream (:class:`StreamReader`) or ``None`` |
| if the process was created with ``stdout=None``. |
| |
| .. attribute:: stderr |
| |
| Standard error stream (:class:`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:`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. |
| |
| A negative value ``-N`` indicates that the child was terminated |
| by signal ``N`` (POSIX only). |
| |
| |
| .. _asyncio-subprocess-threads: |
| |
| Subprocess and Threads |
| ---------------------- |
| |
| Standard asyncio event loop supports running subprocesses from |
| different threads, but there are limitations: |
| |
| * An event loop must run in the main thread. |
| |
| * The child watcher must be instantiated in the main thread |
| before executing subprocesses from other threads. Call the |
| :func:`get_child_watcher` function in the main thread to instantiate |
| the child watcher. |
| |
| Note that alternative event loop implementations might not share |
| the above 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; print(datetime.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. |