Created
January 23, 2026 22:37
-
-
Save timmc-edx/2118ea44c2b8d88dd78b41a4bac5e5b2 to your computer and use it in GitHub Desktop.
Out-of-order stdout behavior from python buffering
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import subprocess | |
| print("=== Start of script") | |
| subprocess.run(['ls', '-ld', '/'], check=True) | |
| print("=== End of script") | |
| # $ python3 test.py | |
| # === Start of script | |
| # drwxr-xr-x 24 root root 4096 Jul 2 2025 / | |
| # === End of script | |
| # | |
| # | |
| # $ python3 test.py | cat | |
| # drwxr-xr-x 24 root root 4096 Jul 2 2025 / | |
| # === Start of script | |
| # === End of script | |
| # | |
| # | |
| # $ PYTHONUNBUFFERED=1 python3 test.py | cat | |
| # === Start of script | |
| # drwxr-xr-x 24 root root 4096 Jul 2 2025 / | |
| # === End of script |
Author
Author
More detail: Python buffering can be disabled, line-based, or full. If stdout is a TTY we get line-based, but otherwise it's full buffering.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Even happens with
print(..., file=sys.stdout)andsubprocess.run(..., stdout=sys.stdout).It turns out that
sys.stdoutis a wrapper that includes a buffer under some circumstances, but subprocess ganks the file descriptor out of the wrapper and passes that directly to the child process. So subprocess is unbuffered, but print is buffered (sometimes).