Skip to content

Instantly share code, notes, and snippets.

@ateska
Last active October 14, 2022 07:57
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ateska/ed4630fef2a1617ae2c44f87b8f0f84e to your computer and use it in GitHub Desktop.
Save ateska/ed4630fef2a1617ae2c44f87b8f0f84e to your computer and use it in GitHub Desktop.
Simultaneously read stdout and stderr from Python `asyncio` create_subprocess_exec
import asyncio
async def run():
proc = await asyncio.create_subprocess_exec(
'/bin/ls', '/etc', '/not-exists',
stdout=asyncio.subprocess.PIPE,
stderr=asyncio.subprocess.PIPE
)
# Prepare set of asynchronous readline() tasks for `stdout` and `stderr` streams
aws = {
asyncio.create_task(proc.stdout.readline(), name="stdout"),
asyncio.create_task(proc.stderr.readline(), name="stderr"),
}
while len(aws) > 0:
done, aws = await asyncio.wait(aws, return_when=asyncio.FIRST_COMPLETED)
for task in done:
line = await task
# If the line is empty, we are at the end of the stream
if len(line) == 0:
continue
print(">>", task.get_name(), line)
# Re-create a readline() task for a respective stream
if task.get_name() == "stdout":
aws.add(asyncio.create_task(proc.stdout.readline(), name="stdout"))
elif task.get_name() == "stderr":
aws.add(asyncio.create_task(proc.stderr.readline(), name="stderr"))
# Wait till the process is finished
returncode = await proc.wait()
print('Exited with code', returncode)
asyncio.run(run())
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment