Steve
Steve

Reputation: 1282

Python vs bash stderr stdout buffering

How can I make my python script behave like bash with regards to stderr and stdout buffering? Bash is buffering stderr and stdout so that printed messages appear in chronological order. The example scripts below illustrate the behavior. Tested with Python 2.7 on Ubuntu 14.04.

cstderr.c

#include <stdio.h>
#include <stdlib.h>
main()
{
    fprintf(stderr, "C out to stderr\n");
    exit(0);
}

bash_stderr.sh

echo Before C cstderr
./cstderr.out
echo After C cstderr

py_stderr.py

#!/usr/bin/env python

import subprocess
print("Before C cstderr")
subprocess.check_call("./cstderr.out")
print("After C cstderr")

Bash behavior

$ ./bash_stderr.sh > outfile 2>&1
$ cat outfile
Before C cstderr
C out to stderr
After C cstderr

Python behavior

$ ./py_stderr.py > outfile 2>&1
$ cat outfile 
C out to stderr
Before C cstderr
After C cstderr

Upvotes: 2

Views: 236

Answers (2)

holdenweb
holdenweb

Reputation: 37003

Look up the -u option in python's miscellaneous options section. It forces standard input, output and error to be unbuffered, so no flushing should be required.

For what it's worth, your program appears to work as expected without modification for both Python 2 and 3 on my Ubuntu 4.2.0-42-generic system, even without the -u option.

Upvotes: 2

Robᵩ
Robᵩ

Reputation: 168616

Bash flushes stdout before any executing any external program. Python doesn't. To get the desired behavior, call sys.stdout.flush() immediately before the subprocess.check_call().

Upvotes: 2

Related Questions