Search code examples
pythonpython-2.7subprocesspopen

Script/subprocess output in time order


I'm working on a python script that generates images in two ways: first it creates the basis images, and then creates new ones to compare to the originals, outputting if there were differences between the two. The main script calls a second script, which does the actual comparison.

The issues I'm running into though is that the output from the two scripts don't line up sequentially. For example, here's the output of running a comparison:

DIFFERENTIAL RUNNING NOW 16:52:02.062000
*** image05.jpg MATCHES ***
MARKER ONE: Differential happened yet? 16:51:51.821000
MARKER TWO: Where's the Diff? 16:51:51.824000
==== Test\Dir ====
Copy Input
Start Comparison
Doing Comparison

The format I want it in though is more like this:

MARKER ONE: Differential happened yet? 16:51:51.821000
MARKER TWO: Where's the Diff? 16:51:51.824000
==== Test\Dir ====
Copy Input
Start Comparison
Doing Comparison
DIFFERENTIAL RUNNING NOW 16:52:02.062000
*** image05.jpg MATCHES ***

So I'm getting the output I need, but looking at the timestamps, they're out of order (for proper organization, the results need to occur after the "Doing Comparison" part)

The code flows like this (generally):

# Imports, arguments
.
.
MARKER ONE
.
.
==== Test\Dir ====
.
.
if creating:
    # create the images here
    # 3 Subprocess are called here, but have no output (that I care about)
    # Images are copied to their home directory
    print "Copy Input"
else: (comparison)
    print "Start Comparison"
    # create new images to be compared
    # Repeat same 3 subprocesses
    print "Doing Comparison"
    # Comparison Subprocess

This point is where the second python script starts up, which compares the pixels between the two images (the one in the home directory, and the one in the temporary directory of the same name) and reports back how many pixels were different, storing them in a .txt file which is then printed to console:

if os.path.isfile(tempImg):
        try:
            ouput = Popen(command, shell=True)
            stdout, stderr = output.communicate()
             if stdout is not None:
                 print stdout
             if stderr is not None:
                 print "Error occurred during execution:"
                 print stderr
        except OSError as e:
            print "Execution failed: " + e
        with open(output) as r:
            result = r.read()
        if result == '0':
            print "*** {} MATCHES ***".format(Base)
        else:
            message = "*** {0} DOES NOT MATCH: {1} pixels differ***".format(Base, result)
            print message
            out = open("{}\img_errs.txt".format(temp), "a")
            out.write(message + "\n")
    else:
        message = "*** {} DOES NOT EXIST ***".format(tempImg)
        print message
        out = open("{}\img_errs.txt".format(temp), "a")
        out.write(message + "\n")

The subprocesses in the parent script are done by a function in the same try/except format shown here. I've tried using a subprocess.call() in place of the Popen/.communicate() portion, as well as a Popen.wait(). Nothing comes out of the stdout, the output from this is only the print statements, but they seem to take priority from the parent script and print first, even though the parent lines are occurring first as evidenced by the time stamps.

Is there any way I can get the parent script's print statements to display before the subprocess? This is all being done in Eclipse Mars using Python 2.7.


Solution

  • This was answered in the comments, but I wanted to put it here to be more easily seen. Credit for this first portion comes from CasualDemon's comment (which is the one I ended up using):

    Adding the flush() line here:

    else: (comparison)
        print "Start Comparison"
        # create new images to be compared
        # Repeat same 3 subprocesses
        print "Doing Comparison"
        sys.stdout.flush()   <-- new
        # Comparison Subprocess
    

    gave me the printing sequences I needed (in time based order).

    Second portion is credit to J.F. Sebastian's answer which also worked. I'm running the script through an External Tools Configuration though, so the -u would need to go in there.

    Old (under arguments):

    script.py ${folder_prompt}
    

    New:

    -u script.py ${folder_prompt}