Process.stdout exposes a redirected subprocess's standard-output stream as a StreamReader. Set stdout to asyncio.subprocess.PIPE when creating the process, then read the stream asynchronously, often line by line. section 13.1.1
Prefixing subprocess output
A write_output coroutine can read Process.stdout with readline(), decode each line, and prepend the originating command before printing it. Run that task alongside process.wait() to report output and completion without confusion. section 13.1.1
Listing 13.3 Using the standard output stream reader
import asyncio
from asyncio import StreamReader
from asyncio.subprocess import Process
async def write_output(prefix: str, stdout: StreamReader):
while line := await stdout.readline():
print(f'[{prefix}]: {line.rstrip().decode()}')
async def main():
program = ['ls', '-la']
process: Process = await asyncio.create_subprocess_exec(*program,
stdout=asyncio
.subprocess.PIPE)
print(f'Process pid is: {process.pid}')
stdout_task = asyncio.create_task(write_output(' '.join(program), process.stdout))
return_code, _ = await asyncio.gather(process.wait(), stdout_task)
print(f'Process returned: {return_code}')
asyncio.run(main())
Shows Process.stdout consumed by a StreamReader task while an asyncio subprocess runs, including the returned process code. section 13.1.1
Always consume substantial piped output. Waiting without reading can deadlock when the pipe fills; process.communicate() provides a simpler alternative for collecting stdout and stderr. section 13.1.1
