Victor Stinner | 0844438 | 2014-02-02 22:43:39 +0100 | [diff] [blame] | 1 | .. currentmodule:: asyncio |
| 2 | |
Victor Stinner | 778015b | 2014-07-11 12:13:39 +0200 | [diff] [blame] | 3 | .. _asyncio-subprocess: |
| 4 | |
Yury Selivanov | 7c7605f | 2018-09-11 09:54:40 -0700 | [diff] [blame] | 5 | ============ |
| 6 | Subprocesses |
| 7 | ============ |
Victor Stinner | 0844438 | 2014-02-02 22:43:39 +0100 | [diff] [blame] | 8 | |
Kyle Stanley | f900064 | 2019-10-10 19:18:46 -0400 | [diff] [blame] | 9 | **Source code:** :source:`Lib/asyncio/subprocess.py`, |
| 10 | :source:`Lib/asyncio/base_subprocess.py` |
| 11 | |
| 12 | ---------------------------------------- |
| 13 | |
Yury Selivanov | 7c7605f | 2018-09-11 09:54:40 -0700 | [diff] [blame] | 14 | This section describes high-level async/await asyncio APIs to |
| 15 | create and manage subprocesses. |
lf | 627d2c8 | 2017-07-25 17:03:51 -0600 | [diff] [blame] | 16 | |
Yury Selivanov | 7372c3b | 2018-09-14 15:11:24 -0700 | [diff] [blame] | 17 | .. _asyncio_example_subprocess_shell: |
| 18 | |
Yury Selivanov | 7c7605f | 2018-09-11 09:54:40 -0700 | [diff] [blame] | 19 | Here's an example of how asyncio can run a shell command and |
Elvis Pranskevichus | 1fa2ec4 | 2018-09-17 19:16:44 -0400 | [diff] [blame] | 20 | obtain its result:: |
Victor Stinner | 984600f | 2014-03-25 09:40:26 +0100 | [diff] [blame] | 21 | |
Yury Selivanov | 7c7605f | 2018-09-11 09:54:40 -0700 | [diff] [blame] | 22 | import asyncio |
Victor Stinner | 984600f | 2014-03-25 09:40:26 +0100 | [diff] [blame] | 23 | |
Yury Selivanov | 7c7605f | 2018-09-11 09:54:40 -0700 | [diff] [blame] | 24 | async def run(cmd): |
| 25 | proc = await asyncio.create_subprocess_shell( |
| 26 | cmd, |
| 27 | stdout=asyncio.subprocess.PIPE, |
| 28 | stderr=asyncio.subprocess.PIPE) |
Victor Stinner | aea8229 | 2014-07-08 23:42:38 +0200 | [diff] [blame] | 29 | |
Yury Selivanov | 7c7605f | 2018-09-11 09:54:40 -0700 | [diff] [blame] | 30 | stdout, stderr = await proc.communicate() |
Victor Stinner | 984600f | 2014-03-25 09:40:26 +0100 | [diff] [blame] | 31 | |
Yury Selivanov | 7c7605f | 2018-09-11 09:54:40 -0700 | [diff] [blame] | 32 | print(f'[{cmd!r} exited with {proc.returncode}]') |
| 33 | if stdout: |
| 34 | print(f'[stdout]\n{stdout.decode()}') |
| 35 | if stderr: |
| 36 | print(f'[stderr]\n{stderr.decode()}') |
Victor Stinner | 778015b | 2014-07-11 12:13:39 +0200 | [diff] [blame] | 37 | |
Yury Selivanov | 7c7605f | 2018-09-11 09:54:40 -0700 | [diff] [blame] | 38 | asyncio.run(run('ls /zzz')) |
| 39 | |
| 40 | will print:: |
| 41 | |
| 42 | ['ls /zzz' exited with 1] |
| 43 | [stderr] |
| 44 | ls: /zzz: No such file or directory |
| 45 | |
| 46 | Because all asyncio subprocess functions are asynchronous and asyncio |
| 47 | provides many tools to work with such functions, it is easy to execute |
| 48 | and monitor multiple subprocesses in parallel. It is indeed trivial |
Elvis Pranskevichus | 1fa2ec4 | 2018-09-17 19:16:44 -0400 | [diff] [blame] | 49 | to modify the above example to run several commands simultaneously:: |
Yury Selivanov | 7c7605f | 2018-09-11 09:54:40 -0700 | [diff] [blame] | 50 | |
| 51 | async def main(): |
| 52 | await asyncio.gather( |
| 53 | run('ls /zzz'), |
| 54 | run('sleep 1; echo "hello"')) |
| 55 | |
| 56 | asyncio.run(main()) |
| 57 | |
| 58 | See also the `Examples`_ subsection. |
Victor Stinner | 778015b | 2014-07-11 12:13:39 +0200 | [diff] [blame] | 59 | |
Victor Stinner | 984600f | 2014-03-25 09:40:26 +0100 | [diff] [blame] | 60 | |
Yury Selivanov | 7c7605f | 2018-09-11 09:54:40 -0700 | [diff] [blame] | 61 | Creating Subprocesses |
| 62 | ===================== |
Victor Stinner | 0844438 | 2014-02-02 22:43:39 +0100 | [diff] [blame] | 63 | |
Dima Tisnek | 1328375 | 2019-04-05 23:02:28 +0900 | [diff] [blame] | 64 | .. coroutinefunction:: create_subprocess_exec(program, \*args, stdin=None, \ |
Yury Selivanov | 7c7605f | 2018-09-11 09:54:40 -0700 | [diff] [blame] | 65 | stdout=None, stderr=None, loop=None, \ |
| 66 | limit=None, \*\*kwds) |
Victor Stinner | 0844438 | 2014-02-02 22:43:39 +0100 | [diff] [blame] | 67 | |
Victor Stinner | 3989205 | 2014-10-14 00:52:07 +0200 | [diff] [blame] | 68 | Create a subprocess. |
Victor Stinner | 0844438 | 2014-02-02 22:43:39 +0100 | [diff] [blame] | 69 | |
Yury Selivanov | 7c7605f | 2018-09-11 09:54:40 -0700 | [diff] [blame] | 70 | The *limit* argument sets the buffer limit for :class:`StreamReader` |
| 71 | wrappers for :attr:`Process.stdout` and :attr:`Process.stderr` |
Carol Willing | 4e824e9 | 2018-09-13 18:28:19 -0700 | [diff] [blame] | 72 | (if :attr:`subprocess.PIPE` is passed to *stdout* and *stderr* arguments). |
Victor Stinner | 3989205 | 2014-10-14 00:52:07 +0200 | [diff] [blame] | 73 | |
| 74 | Return a :class:`~asyncio.subprocess.Process` instance. |
Victor Stinner | 984600f | 2014-03-25 09:40:26 +0100 | [diff] [blame] | 75 | |
Yury Selivanov | 7c7605f | 2018-09-11 09:54:40 -0700 | [diff] [blame] | 76 | See the documentation of :meth:`loop.subprocess_exec` for other |
| 77 | parameters. |
Victor Stinner | 0844438 | 2014-02-02 22:43:39 +0100 | [diff] [blame] | 78 | |
Andrew Svetlov | a488879 | 2019-09-12 15:40:40 +0300 | [diff] [blame] | 79 | .. deprecated-removed:: 3.8 3.10 |
| 80 | |
| 81 | The *loop* parameter. |
| 82 | |
Yury Selivanov | 7c7605f | 2018-09-11 09:54:40 -0700 | [diff] [blame] | 83 | .. coroutinefunction:: create_subprocess_shell(cmd, stdin=None, \ |
| 84 | stdout=None, stderr=None, loop=None, \ |
| 85 | limit=None, \*\*kwds) |
Victor Stinner | 0844438 | 2014-02-02 22:43:39 +0100 | [diff] [blame] | 86 | |
Elvis Pranskevichus | 1fa2ec4 | 2018-09-17 19:16:44 -0400 | [diff] [blame] | 87 | Run the *cmd* shell command. |
Victor Stinner | 0844438 | 2014-02-02 22:43:39 +0100 | [diff] [blame] | 88 | |
Yury Selivanov | 7c7605f | 2018-09-11 09:54:40 -0700 | [diff] [blame] | 89 | The *limit* argument sets the buffer limit for :class:`StreamReader` |
| 90 | wrappers for :attr:`Process.stdout` and :attr:`Process.stderr` |
Carol Willing | 4e824e9 | 2018-09-13 18:28:19 -0700 | [diff] [blame] | 91 | (if :attr:`subprocess.PIPE` is passed to *stdout* and *stderr* arguments). |
Victor Stinner | 3989205 | 2014-10-14 00:52:07 +0200 | [diff] [blame] | 92 | |
| 93 | Return a :class:`~asyncio.subprocess.Process` instance. |
| 94 | |
Yury Selivanov | 7c7605f | 2018-09-11 09:54:40 -0700 | [diff] [blame] | 95 | See the documentation of :meth:`loop.subprocess_shell` for other |
| 96 | parameters. |
Victor Stinner | 984600f | 2014-03-25 09:40:26 +0100 | [diff] [blame] | 97 | |
Carol Willing | 4e824e9 | 2018-09-13 18:28:19 -0700 | [diff] [blame] | 98 | .. important:: |
Victor Stinner | 984600f | 2014-03-25 09:40:26 +0100 | [diff] [blame] | 99 | |
Victor Stinner | 3989205 | 2014-10-14 00:52:07 +0200 | [diff] [blame] | 100 | It is the application's responsibility to ensure that all whitespace and |
Elvis Pranskevichus | 1fa2ec4 | 2018-09-17 19:16:44 -0400 | [diff] [blame] | 101 | special characters are quoted appropriately to avoid `shell injection |
Georg Brandl | 5d94134 | 2016-02-26 19:37:12 +0100 | [diff] [blame] | 102 | <https://en.wikipedia.org/wiki/Shell_injection#Shell_injection>`_ |
Victor Stinner | 3989205 | 2014-10-14 00:52:07 +0200 | [diff] [blame] | 103 | vulnerabilities. The :func:`shlex.quote` function can be used to properly |
Elvis Pranskevichus | 1fa2ec4 | 2018-09-17 19:16:44 -0400 | [diff] [blame] | 104 | escape whitespace and special shell characters in strings that are going |
| 105 | to be used to construct shell commands. |
Victor Stinner | 984600f | 2014-03-25 09:40:26 +0100 | [diff] [blame] | 106 | |
Andrew Svetlov | a488879 | 2019-09-12 15:40:40 +0300 | [diff] [blame] | 107 | .. deprecated-removed:: 3.8 3.10 |
| 108 | |
| 109 | The *loop* parameter. |
| 110 | |
Yury Selivanov | 7c7605f | 2018-09-11 09:54:40 -0700 | [diff] [blame] | 111 | .. note:: |
| 112 | |
Elvis Pranskevichus | 1fa2ec4 | 2018-09-17 19:16:44 -0400 | [diff] [blame] | 113 | The default asyncio event loop implementation on **Windows** does not |
| 114 | support subprocesses. Subprocesses are available for Windows if a |
| 115 | :class:`ProactorEventLoop` is used. |
Yury Selivanov | 7c7605f | 2018-09-11 09:54:40 -0700 | [diff] [blame] | 116 | See :ref:`Subprocess Support on Windows <asyncio-windows-subprocess>` |
| 117 | for details. |
Victor Stinner | 984600f | 2014-03-25 09:40:26 +0100 | [diff] [blame] | 118 | |
Victor Stinner | 0844438 | 2014-02-02 22:43:39 +0100 | [diff] [blame] | 119 | .. seealso:: |
| 120 | |
Elvis Pranskevichus | 1fa2ec4 | 2018-09-17 19:16:44 -0400 | [diff] [blame] | 121 | asyncio also has the following *low-level* APIs to work with subprocesses: |
Yury Selivanov | 7c7605f | 2018-09-11 09:54:40 -0700 | [diff] [blame] | 122 | :meth:`loop.subprocess_exec`, :meth:`loop.subprocess_shell`, |
| 123 | :meth:`loop.connect_read_pipe`, :meth:`loop.connect_write_pipe`, |
| 124 | as well as the :ref:`Subprocess Transports <asyncio-subprocess-transports>` |
| 125 | and :ref:`Subprocess Protocols <asyncio-subprocess-protocols>`. |
Victor Stinner | 0844438 | 2014-02-02 22:43:39 +0100 | [diff] [blame] | 126 | |
| 127 | |
| 128 | Constants |
Yury Selivanov | 7c7605f | 2018-09-11 09:54:40 -0700 | [diff] [blame] | 129 | ========= |
Victor Stinner | 0844438 | 2014-02-02 22:43:39 +0100 | [diff] [blame] | 130 | |
| 131 | .. data:: asyncio.subprocess.PIPE |
| 132 | |
Yury Selivanov | 7c7605f | 2018-09-11 09:54:40 -0700 | [diff] [blame] | 133 | Can be passed to the *stdin*, *stdout* or *stderr* parameters. |
| 134 | |
| 135 | If *PIPE* is passed to *stdin* argument, the |
| 136 | :attr:`Process.stdin <asyncio.subprocess.Process.stdin>` attribute |
| 137 | will point to a :class:`StreamWriter` instance. |
| 138 | |
| 139 | If *PIPE* is passed to *stdout* or *stderr* arguments, the |
| 140 | :attr:`Process.stdout <asyncio.subprocess.Process.stdout>` and |
| 141 | :attr:`Process.stderr <asyncio.subprocess.Process.stderr>` |
| 142 | attributes will point to :class:`StreamReader` instances. |
Victor Stinner | 0844438 | 2014-02-02 22:43:39 +0100 | [diff] [blame] | 143 | |
| 144 | .. data:: asyncio.subprocess.STDOUT |
| 145 | |
Elvis Pranskevichus | 1fa2ec4 | 2018-09-17 19:16:44 -0400 | [diff] [blame] | 146 | Special value that can be used as the *stderr* argument and indicates |
| 147 | that standard error should be redirected into standard output. |
Victor Stinner | 0844438 | 2014-02-02 22:43:39 +0100 | [diff] [blame] | 148 | |
| 149 | .. data:: asyncio.subprocess.DEVNULL |
| 150 | |
Elvis Pranskevichus | 1fa2ec4 | 2018-09-17 19:16:44 -0400 | [diff] [blame] | 151 | Special value that can be used as the *stdin*, *stdout* or *stderr* argument |
| 152 | to process creation functions. It indicates that the special file |
| 153 | :data:`os.devnull` will be used for the corresponding subprocess stream. |
Victor Stinner | 0844438 | 2014-02-02 22:43:39 +0100 | [diff] [blame] | 154 | |
| 155 | |
Yury Selivanov | 7c7605f | 2018-09-11 09:54:40 -0700 | [diff] [blame] | 156 | Interacting with Subprocesses |
| 157 | ============================= |
| 158 | |
| 159 | Both :func:`create_subprocess_exec` and :func:`create_subprocess_shell` |
Elvis Pranskevichus | 1fa2ec4 | 2018-09-17 19:16:44 -0400 | [diff] [blame] | 160 | functions return instances of the *Process* class. *Process* is a high-level |
| 161 | wrapper that allows communicating with subprocesses and watching for |
| 162 | their completion. |
Victor Stinner | 0844438 | 2014-02-02 22:43:39 +0100 | [diff] [blame] | 163 | |
| 164 | .. class:: asyncio.subprocess.Process |
| 165 | |
Yury Selivanov | 7c7605f | 2018-09-11 09:54:40 -0700 | [diff] [blame] | 166 | An object that wraps OS processes created by the |
| 167 | :func:`create_subprocess_exec` and :func:`create_subprocess_shell` |
| 168 | functions. |
Victor Stinner | b79eb05 | 2014-02-03 23:08:14 +0100 | [diff] [blame] | 169 | |
Yury Selivanov | 7c7605f | 2018-09-11 09:54:40 -0700 | [diff] [blame] | 170 | This class is designed to have a similar API to the |
| 171 | :class:`subprocess.Popen` class, but there are some |
| 172 | notable differences: |
Victor Stinner | b79eb05 | 2014-02-03 23:08:14 +0100 | [diff] [blame] | 173 | |
Yury Selivanov | 7c7605f | 2018-09-11 09:54:40 -0700 | [diff] [blame] | 174 | * unlike Popen, Process instances do not have an equivalent to |
| 175 | the :meth:`~subprocess.Popen.poll` method; |
Victor Stinner | b79eb05 | 2014-02-03 23:08:14 +0100 | [diff] [blame] | 176 | |
Yury Selivanov | 7c7605f | 2018-09-11 09:54:40 -0700 | [diff] [blame] | 177 | * the :meth:`~asyncio.subprocess.Process.communicate` and |
Elvis Pranskevichus | 1fa2ec4 | 2018-09-17 19:16:44 -0400 | [diff] [blame] | 178 | :meth:`~asyncio.subprocess.Process.wait` methods don't have a |
Yury Selivanov | 7c7605f | 2018-09-11 09:54:40 -0700 | [diff] [blame] | 179 | *timeout* parameter: use the :func:`wait_for` function; |
| 180 | |
| 181 | * the :meth:`Process.wait() <asyncio.subprocess.Process.wait>` method |
| 182 | is asynchronous, whereas :meth:`subprocess.Popen.wait` method |
| 183 | is implemented as a blocking busy loop; |
| 184 | |
| 185 | * the *universal_newlines* parameter is not supported. |
| 186 | |
| 187 | This class is :ref:`not thread safe <asyncio-multithreading>`. |
| 188 | |
| 189 | See also the :ref:`Subprocess and Threads <asyncio-subprocess-threads>` |
| 190 | section. |
Victor Stinner | 8370496 | 2015-02-25 14:24:15 +0100 | [diff] [blame] | 191 | |
Victor Stinner | bdd574d | 2015-02-12 22:49:18 +0100 | [diff] [blame] | 192 | .. coroutinemethod:: wait() |
Victor Stinner | b79eb05 | 2014-02-03 23:08:14 +0100 | [diff] [blame] | 193 | |
Elvis Pranskevichus | 1fa2ec4 | 2018-09-17 19:16:44 -0400 | [diff] [blame] | 194 | Wait for the child process to terminate. |
Victor Stinner | b79eb05 | 2014-02-03 23:08:14 +0100 | [diff] [blame] | 195 | |
Yury Selivanov | 7c7605f | 2018-09-11 09:54:40 -0700 | [diff] [blame] | 196 | Set and return the :attr:`returncode` attribute. |
Victor Stinner | b79eb05 | 2014-02-03 23:08:14 +0100 | [diff] [blame] | 197 | |
Victor Stinner | 3989205 | 2014-10-14 00:52:07 +0200 | [diff] [blame] | 198 | .. note:: |
Victor Stinner | 0844438 | 2014-02-02 22:43:39 +0100 | [diff] [blame] | 199 | |
Yury Selivanov | 7c7605f | 2018-09-11 09:54:40 -0700 | [diff] [blame] | 200 | This method can deadlock when using ``stdout=PIPE`` or |
| 201 | ``stderr=PIPE`` and the child process generates so much output |
| 202 | that it blocks waiting for the OS pipe buffer to accept |
| 203 | more data. Use the :meth:`communicate` method when using pipes |
| 204 | to avoid this condition. |
Victor Stinner | 0844438 | 2014-02-02 22:43:39 +0100 | [diff] [blame] | 205 | |
Victor Stinner | bdd574d | 2015-02-12 22:49:18 +0100 | [diff] [blame] | 206 | .. coroutinemethod:: communicate(input=None) |
Victor Stinner | 0844438 | 2014-02-02 22:43:39 +0100 | [diff] [blame] | 207 | |
Yury Selivanov | 7c7605f | 2018-09-11 09:54:40 -0700 | [diff] [blame] | 208 | Interact with process: |
Victor Stinner | 0844438 | 2014-02-02 22:43:39 +0100 | [diff] [blame] | 209 | |
Yury Selivanov | 7c7605f | 2018-09-11 09:54:40 -0700 | [diff] [blame] | 210 | 1. send data to *stdin* (if *input* is not ``None``); |
| 211 | 2. read data from *stdout* and *stderr*, until EOF is reached; |
| 212 | 3. wait for process to terminate. |
Victor Stinner | 3989205 | 2014-10-14 00:52:07 +0200 | [diff] [blame] | 213 | |
Yury Selivanov | 7c7605f | 2018-09-11 09:54:40 -0700 | [diff] [blame] | 214 | The optional *input* argument is the data (:class:`bytes` object) |
| 215 | that will be sent to the child process. |
Victor Stinner | cc996b5 | 2014-07-17 12:25:27 +0200 | [diff] [blame] | 216 | |
Yury Selivanov | 7c7605f | 2018-09-11 09:54:40 -0700 | [diff] [blame] | 217 | Return a tuple ``(stdout_data, stderr_data)``. |
Victor Stinner | 0844438 | 2014-02-02 22:43:39 +0100 | [diff] [blame] | 218 | |
Yury Selivanov | 7c7605f | 2018-09-11 09:54:40 -0700 | [diff] [blame] | 219 | If either :exc:`BrokenPipeError` or :exc:`ConnectionResetError` |
| 220 | exception is raised when writing *input* into *stdin*, the |
| 221 | exception is ignored. This condition occurs when the process |
| 222 | exits before all data are written into *stdin*. |
Victor Stinner | 3989205 | 2014-10-14 00:52:07 +0200 | [diff] [blame] | 223 | |
Carol Willing | 4e824e9 | 2018-09-13 18:28:19 -0700 | [diff] [blame] | 224 | If it is desired to send data to the process' *stdin*, |
Yury Selivanov | 7c7605f | 2018-09-11 09:54:40 -0700 | [diff] [blame] | 225 | the process needs to be created with ``stdin=PIPE``. Similarly, |
| 226 | to get anything other than ``None`` in the result tuple, the |
| 227 | process has to be created with ``stdout=PIPE`` and/or |
| 228 | ``stderr=PIPE`` arguments. |
Victor Stinner | 0844438 | 2014-02-02 22:43:39 +0100 | [diff] [blame] | 229 | |
Yury Selivanov | 7c7605f | 2018-09-11 09:54:40 -0700 | [diff] [blame] | 230 | Note, that the data read is buffered in memory, so do not use |
| 231 | this method if the data size is large or unlimited. |
Victor Stinner | cc996b5 | 2014-07-17 12:25:27 +0200 | [diff] [blame] | 232 | |
Brian Curtin | a1afeec | 2014-02-08 18:36:14 -0600 | [diff] [blame] | 233 | .. method:: send_signal(signal) |
Victor Stinner | 0844438 | 2014-02-02 22:43:39 +0100 | [diff] [blame] | 234 | |
| 235 | Sends the signal *signal* to the child process. |
| 236 | |
| 237 | .. note:: |
| 238 | |
| 239 | On Windows, :py:data:`SIGTERM` is an alias for :meth:`terminate`. |
| 240 | ``CTRL_C_EVENT`` and ``CTRL_BREAK_EVENT`` can be sent to processes |
| 241 | started with a *creationflags* parameter which includes |
| 242 | ``CREATE_NEW_PROCESS_GROUP``. |
| 243 | |
| 244 | .. method:: terminate() |
| 245 | |
Elvis Pranskevichus | 1fa2ec4 | 2018-09-17 19:16:44 -0400 | [diff] [blame] | 246 | Stop the child process. |
Yury Selivanov | 7c7605f | 2018-09-11 09:54:40 -0700 | [diff] [blame] | 247 | |
Elvis Pranskevichus | 1fa2ec4 | 2018-09-17 19:16:44 -0400 | [diff] [blame] | 248 | On POSIX systems this method sends :py:data:`signal.SIGTERM` to the |
Yury Selivanov | 7c7605f | 2018-09-11 09:54:40 -0700 | [diff] [blame] | 249 | child process. |
| 250 | |
| 251 | On Windows the Win32 API function :c:func:`TerminateProcess` is |
| 252 | called to stop the child process. |
Victor Stinner | 0844438 | 2014-02-02 22:43:39 +0100 | [diff] [blame] | 253 | |
Victor Stinner | 3989205 | 2014-10-14 00:52:07 +0200 | [diff] [blame] | 254 | .. method:: kill() |
Victor Stinner | 0844438 | 2014-02-02 22:43:39 +0100 | [diff] [blame] | 255 | |
Yury Selivanov | 7c7605f | 2018-09-11 09:54:40 -0700 | [diff] [blame] | 256 | Kill the child. |
| 257 | |
Elvis Pranskevichus | 1fa2ec4 | 2018-09-17 19:16:44 -0400 | [diff] [blame] | 258 | On POSIX systems this method sends :py:data:`SIGKILL` to the child |
Yury Selivanov | 7c7605f | 2018-09-11 09:54:40 -0700 | [diff] [blame] | 259 | process. |
| 260 | |
| 261 | On Windows this method is an alias for :meth:`terminate`. |
Victor Stinner | 0844438 | 2014-02-02 22:43:39 +0100 | [diff] [blame] | 262 | |
Victor Stinner | 3989205 | 2014-10-14 00:52:07 +0200 | [diff] [blame] | 263 | .. attribute:: stdin |
| 264 | |
Yury Selivanov | 7c7605f | 2018-09-11 09:54:40 -0700 | [diff] [blame] | 265 | Standard input stream (:class:`StreamWriter`) or ``None`` |
| 266 | if the process was created with ``stdin=None``. |
Victor Stinner | 3989205 | 2014-10-14 00:52:07 +0200 | [diff] [blame] | 267 | |
| 268 | .. attribute:: stdout |
| 269 | |
Yury Selivanov | 7c7605f | 2018-09-11 09:54:40 -0700 | [diff] [blame] | 270 | Standard output stream (:class:`StreamReader`) or ``None`` |
| 271 | if the process was created with ``stdout=None``. |
Victor Stinner | 3989205 | 2014-10-14 00:52:07 +0200 | [diff] [blame] | 272 | |
| 273 | .. attribute:: stderr |
| 274 | |
Yury Selivanov | 7c7605f | 2018-09-11 09:54:40 -0700 | [diff] [blame] | 275 | Standard error stream (:class:`StreamReader`) or ``None`` |
| 276 | if the process was created with ``stderr=None``. |
Victor Stinner | 3989205 | 2014-10-14 00:52:07 +0200 | [diff] [blame] | 277 | |
| 278 | .. warning:: |
| 279 | |
Yury Selivanov | 7c7605f | 2018-09-11 09:54:40 -0700 | [diff] [blame] | 280 | Use the :meth:`communicate` method rather than |
| 281 | :attr:`process.stdin.write() <stdin>`, |
| 282 | :attr:`await process.stdout.read() <stdout>` or |
Carol Willing | 4e824e9 | 2018-09-13 18:28:19 -0700 | [diff] [blame] | 283 | :attr:`await process.stderr.read <stderr>`. |
| 284 | This avoids deadlocks due to streams pausing reading or writing |
Yury Selivanov | 7c7605f | 2018-09-11 09:54:40 -0700 | [diff] [blame] | 285 | and blocking the child process. |
Victor Stinner | 3989205 | 2014-10-14 00:52:07 +0200 | [diff] [blame] | 286 | |
| 287 | .. attribute:: pid |
| 288 | |
Yury Selivanov | 7c7605f | 2018-09-11 09:54:40 -0700 | [diff] [blame] | 289 | Process identification number (PID). |
Victor Stinner | 3989205 | 2014-10-14 00:52:07 +0200 | [diff] [blame] | 290 | |
| 291 | Note that for processes created by the :func:`create_subprocess_shell` |
Yury Selivanov | 7c7605f | 2018-09-11 09:54:40 -0700 | [diff] [blame] | 292 | function, this attribute is the PID of the spawned shell. |
Victor Stinner | 3989205 | 2014-10-14 00:52:07 +0200 | [diff] [blame] | 293 | |
| 294 | .. attribute:: returncode |
| 295 | |
Yury Selivanov | 7c7605f | 2018-09-11 09:54:40 -0700 | [diff] [blame] | 296 | Return code of the process when it exits. |
Victor Stinner | 3989205 | 2014-10-14 00:52:07 +0200 | [diff] [blame] | 297 | |
Yury Selivanov | 7c7605f | 2018-09-11 09:54:40 -0700 | [diff] [blame] | 298 | A ``None`` value indicates that the process has not terminated yet. |
| 299 | |
| 300 | A negative value ``-N`` indicates that the child was terminated |
Elvis Pranskevichus | 1fa2ec4 | 2018-09-17 19:16:44 -0400 | [diff] [blame] | 301 | by signal ``N`` (POSIX only). |
Victor Stinner | 7bdf786 | 2014-03-16 21:29:31 +0100 | [diff] [blame] | 302 | |
Victor Stinner | e48d4db | 2014-02-03 23:26:28 +0100 | [diff] [blame] | 303 | |
Victor Stinner | 399c59d | 2015-01-09 01:32:02 +0100 | [diff] [blame] | 304 | .. _asyncio-subprocess-threads: |
| 305 | |
Yury Selivanov | 7c7605f | 2018-09-11 09:54:40 -0700 | [diff] [blame] | 306 | Subprocess and Threads |
Victor Stinner | 5492d35 | 2015-09-02 15:39:01 +0200 | [diff] [blame] | 307 | ---------------------- |
Victor Stinner | 399c59d | 2015-01-09 01:32:02 +0100 | [diff] [blame] | 308 | |
Andrew Svetlov | 0d671c0 | 2019-06-30 12:54:59 +0300 | [diff] [blame] | 309 | Standard asyncio event loop supports running subprocesses from different threads by |
| 310 | default. |
Victor Stinner | 399c59d | 2015-01-09 01:32:02 +0100 | [diff] [blame] | 311 | |
Andrew Svetlov | 0d671c0 | 2019-06-30 12:54:59 +0300 | [diff] [blame] | 312 | On Windows subprocesses are provided by :class:`ProactorEventLoop` only (default), |
| 313 | :class:`SelectorEventLoop` has no subprocess support. |
Victor Stinner | 399c59d | 2015-01-09 01:32:02 +0100 | [diff] [blame] | 314 | |
Andrew Svetlov | 0d671c0 | 2019-06-30 12:54:59 +0300 | [diff] [blame] | 315 | On UNIX *child watchers* are used for subprocess finish waiting, see |
| 316 | :ref:`asyncio-watchers` for more info. |
Yury Selivanov | 7c7605f | 2018-09-11 09:54:40 -0700 | [diff] [blame] | 317 | |
Andrew Svetlov | 0d671c0 | 2019-06-30 12:54:59 +0300 | [diff] [blame] | 318 | |
| 319 | .. versionchanged:: 3.8 |
| 320 | |
| 321 | UNIX switched to use :class:`ThreadedChildWatcher` for spawning subprocesses from |
| 322 | different threads without any limitation. |
| 323 | |
| 324 | Spawning a subprocess with *inactive* current child watcher raises |
| 325 | :exc:`RuntimeError`. |
| 326 | |
| 327 | Note that alternative event loop implementations might have own limitations; |
| 328 | please refer to their documentation. |
Victor Stinner | 8370496 | 2015-02-25 14:24:15 +0100 | [diff] [blame] | 329 | |
Victor Stinner | 399c59d | 2015-01-09 01:32:02 +0100 | [diff] [blame] | 330 | .. seealso:: |
| 331 | |
| 332 | The :ref:`Concurrency and multithreading in asyncio |
| 333 | <asyncio-multithreading>` section. |
| 334 | |
| 335 | |
Yury Selivanov | 7c7605f | 2018-09-11 09:54:40 -0700 | [diff] [blame] | 336 | Examples |
| 337 | -------- |
Victor Stinner | e48d4db | 2014-02-03 23:26:28 +0100 | [diff] [blame] | 338 | |
Yury Selivanov | 7c7605f | 2018-09-11 09:54:40 -0700 | [diff] [blame] | 339 | An example using the :class:`~asyncio.subprocess.Process` class to |
| 340 | control a subprocess and the :class:`StreamReader` class to read from |
Elvis Pranskevichus | 1fa2ec4 | 2018-09-17 19:16:44 -0400 | [diff] [blame] | 341 | its standard output. |
Victor Stinner | 3989205 | 2014-10-14 00:52:07 +0200 | [diff] [blame] | 342 | |
Yury Selivanov | 394374e | 2018-09-17 15:35:24 -0400 | [diff] [blame] | 343 | .. _asyncio_example_create_subprocess_exec: |
| 344 | |
Yury Selivanov | 7c7605f | 2018-09-11 09:54:40 -0700 | [diff] [blame] | 345 | The subprocess is created by the :func:`create_subprocess_exec` |
Victor Stinner | 3989205 | 2014-10-14 00:52:07 +0200 | [diff] [blame] | 346 | function:: |
| 347 | |
Yury Selivanov | 7c7605f | 2018-09-11 09:54:40 -0700 | [diff] [blame] | 348 | import asyncio |
Victor Stinner | 3989205 | 2014-10-14 00:52:07 +0200 | [diff] [blame] | 349 | import sys |
| 350 | |
Mikhail Terekhov | d2ac400 | 2018-08-07 16:29:06 -0400 | [diff] [blame] | 351 | async def get_date(): |
Victor Stinner | 3989205 | 2014-10-14 00:52:07 +0200 | [diff] [blame] | 352 | code = 'import datetime; print(datetime.datetime.now())' |
| 353 | |
Yury Selivanov | 7c7605f | 2018-09-11 09:54:40 -0700 | [diff] [blame] | 354 | # Create the subprocess; redirect the standard output |
| 355 | # into a pipe. |
Andrew Svetlov | 8874342 | 2017-12-11 17:35:49 +0200 | [diff] [blame] | 356 | proc = await asyncio.create_subprocess_exec( |
| 357 | sys.executable, '-c', code, |
| 358 | stdout=asyncio.subprocess.PIPE) |
Victor Stinner | 3989205 | 2014-10-14 00:52:07 +0200 | [diff] [blame] | 359 | |
Yury Selivanov | 7c7605f | 2018-09-11 09:54:40 -0700 | [diff] [blame] | 360 | # Read one line of output. |
Andrew Svetlov | 8874342 | 2017-12-11 17:35:49 +0200 | [diff] [blame] | 361 | data = await proc.stdout.readline() |
Victor Stinner | 3989205 | 2014-10-14 00:52:07 +0200 | [diff] [blame] | 362 | line = data.decode('ascii').rstrip() |
| 363 | |
Yury Selivanov | 7c7605f | 2018-09-11 09:54:40 -0700 | [diff] [blame] | 364 | # Wait for the subprocess exit. |
Andrew Svetlov | 8874342 | 2017-12-11 17:35:49 +0200 | [diff] [blame] | 365 | await proc.wait() |
Victor Stinner | 3989205 | 2014-10-14 00:52:07 +0200 | [diff] [blame] | 366 | return line |
| 367 | |
Yury Selivanov | 7c7605f | 2018-09-11 09:54:40 -0700 | [diff] [blame] | 368 | date = asyncio.run(get_date()) |
| 369 | print(f"Current date: {date}") |
| 370 | |
| 371 | |
Yury Selivanov | 394374e | 2018-09-17 15:35:24 -0400 | [diff] [blame] | 372 | See also the :ref:`same example <asyncio_example_subprocess_proto>` |
Yury Selivanov | 7c7605f | 2018-09-11 09:54:40 -0700 | [diff] [blame] | 373 | written using low-level APIs. |