ppyvabw
ppyvabw

Reputation: 141

Start a subprocess, wait for it to complete and then retrieve data in Python

I'm struggling to get some python script to start a subprocess, wait until it completes and then retrieve the required data. I'm quite new to Python.

The command I wish to run as a subprocess is

    ./bin.testing/Eva -t --suite="temp0"

Running that command by hand in the Linux terminal produces:

    in terminal mode
    Evaluation error = 16.7934

I want to run the command as a python sub-process, and receive the output back. However, everything I try seems to skip the second line (ultimately, it's the second line that I want.) At the moment, I have this:

    def job(self,fen_file):
        from subprocess import Popen, PIPE
        from sys import exit

        try:
            eva=Popen('{0}/Eva -t --suite"{0}"'.format(self.exedir,fen_file),shell=True,stdout=PIPE,stderr=PIPE)            
            stdout,stderr=eva.communicate()
        except:
            print ('Error running test suite '+fen_file)
            exit("Stopping")

        print(stdout) 
        .
        .
        .
        return 0

All this seems to produce is

    in terminal mode

    0

with the important line missing. The print statement is just so I can see what I am getting back from the sub-process -- the intention is that it will be replaced with code that processes the number from the second line and returns the output (here I'm just returning 0 just so I can get this particular bit to work first. The caller of this function prints the result, which is why there is a zero at the end of the output.) exedir is just the directory of the executable for the sub-process, and fen-file is just an ascii file that the sub-process needs. I have tried removing the 'in terminal mode' from the source code of the sub-process and re compiling it, but that doesn't work -- it still doesn't return the important second line.

Thanks in advance; I expect what I am doing wrong is really very simple.

Edit: I ought to add that the subprocess Eva can take a second or two to complete.

Upvotes: 2

Views: 256

Answers (2)

player87
player87

Reputation: 1791

Try using subprocess check_output.

output_lines = subprocess.check_output(['./bin.testing/Eva', '-t', '--suite="temp0"'])
for line in output_lines.splitlines():
    print(line)

Upvotes: 0

rrauenza
rrauenza

Reputation: 6993

Since the 2nd line is an error message, it's probably stored in your stderr variable!

To know for sure you can print your stderr in your code, or you can run the program on the command line and see if the output is split into stdout and stderr. One easy way is to do ./bin.testing/Eva -t --suite="temp0" > /dev/null. Any messages you get are stderr since stdout is redirected to /dev/null.

Also, typically with Popen the shell=True option is discouraged unless really needed. Instead pass a list:

[os.path.join(self.exedir, 'Eva'), '-t', '--suite=' + fen_file], shell=False, ...

This can avoid problems down the line if one of your arguments would normally be interpreted by the shell. (Note, I removed the ""'s, because the shell would normally eat those for you!)

Upvotes: 2

Related Questions