When trying to write the stdout from a Python script to a text file (python script.py > log
), the text file is created when the command is started, but the actual content isn't written until the Python script finishes. For example:
script.py:
import time
for i in range(10):
print('bla')
time.sleep(5)
prints to stdout every 5 seconds when called with python script.py
, but when I call python script.py > log
, the size of the log file stays zero until the script finishes. Is it possible to directly write to the log file, such that you can follow the progress of the script (e.g. using tail
)?
EDIT It turns out that python -u script.py
does the trick, I didn't know about the buffering of stdout.
Best Answer
This is happening because normally when process STDOUT is redirected to something other than a terminal, then the output is buffered into some OS-specific-sized buffer (perhaps 4k or 8k in many cases). Conversely, when outputting to a terminal, STDOUT will be line-buffered or not buffered at all, so you'll see output after each
\n
or for each character.You can generally change the STDOUT buffering with the
stdbuf
utility:Now if you
tail -F log
, you should see each line output immediately as it is generated.Alternatively explicit flushing of the output stream after each print should achieve the same. It looks like
sys.stdout.flush()
should achieve this in Python. If you are using Python 3.3 or newer, theprint
function also has aflush
keyword that does this:print('hello', flush=True)
.