1

I have a simple script that first cleans a directory(deletes stale binaries) and then builds a bunch of files using make and then go on to do few other things. I want to print indicative messages as the script is about to execute each step as in: print deleting, delete, print building, make ... The script always prints the indicative messages after executing delete and make. Here is the my script.

def build():
      print("deleting stale binaries ...")
      os.system("make clean")
      print("starting build ..")
      os.system("make")
      return;

def main():
    build()

if __name__=="__main__":
    main()

Here is the output I see:

rm -rf *.so *.a

gcc -Wall -other options file1.c file2.c ... ... the rest of the build output ...

And then it prints all the print statements

deleting stale binaries ...

starting build ...

I have moved around the print statements by putting them in different order, inside main but nothing works. Can someone please help me understand what is going on here?

Community
  • 1
  • 1
droidian
  • 79
  • 10
  • 2
    Two separate processes producing output. The output order may be different from one run to another. – Fred Larson Apr 13 '20 at 20:56
  • 4
    I'd recommend using [`subprocess`](http://docs.python.org/3/library/subprocess.html) instead of `os.system` – Alex Apr 13 '20 at 20:56
  • 1
    A [flush](https://stackoverflow.com/a/230774/10077) might help. Have you tried that? – Fred Larson Apr 13 '20 at 20:58
  • While all of the above statements are accurate, isn't the OP saying that their `print` statements are coming after the output of the `os.system` calls? – SteveK Apr 13 '20 at 20:58
  • @SteveK yes. But `os.system` iirc just emits straight to stdout, whereas `subprocess` gives you finer (and more secure) control over your command and it's output. IMO it's the right tool for this job. – Alex Apr 13 '20 at 21:00
  • @Alex, with subprocess, the problem is getting reversed. The prints are getting printed first and then the system output such as the output of delete and make. – droidian Apr 13 '20 at 21:26

1 Answers1

3

You've run into Python's I/O buffering, which will delay writes to improve efficiency, especially when the CPU is engaged in running computationally intensive processes such as gcc. Assuming you're running a recent Python > 3.3, adding a "flush" to your print statement, as in

print("starting build ..", flush=True) should help.

An alternative for older versions of Python might be calling

import sys

....

sys.stdout.flush()

following your print call.

Community
  • 1
  • 1
sevenr
  • 379
  • 3
  • 7