Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Saving stdout from subprocess.Popen to file, plus writing more stuff to the file

Tags:

I'm writing a python script that uses subprocess.Popen to execute two programs (from compiled C code) which each produce stdout. The script gets that output and saves it to a file. Because the output is sometimes large enough to overwhelm subprocess.PIPE, causing the script to hang, I send the stdout directly to the log file. I want to have my script write something to the beginning and end of the file, and between the two subprocess.Popen calls. However, when I look at my log file, anything I wrote to the log file from the script is all together at the top of the file, followed by all the executable stdout. How can I interleave my added text to the file?

def run(cmd, logfile):     p = subprocess.Popen(cmd, shell=True, universal_newlines=True, stdout=logfile)     return p  def runTest(path, flags, name):     log = open(name, "w")     print >> log, "Calling executable A"     a_ret = run(path + "executable_a_name" + flags, log)     print >> log, "Calling executable B"     b_ret = run(path + "executable_b_name" + flags, log)     print >> log, "More stuff"     log.close() 

The log file has: Calling executable A Calling executable B More stuff [... stdout from both executables ...]

Is there a way I can flush A's stdout to the log after calling Popen, for example? One more thing that might be relevant: Executable A starts then pends on B, and after B prints stuff and finishes, A then prints more stuff and finishes.

I'm using Python 2.4 on RHE Linux.

like image 331
jasper77 Avatar asked Jul 06 '10 22:07

jasper77


People also ask

How do I save output from subprocess?

If you want to capture the output of the command, you should use subprocess. check_output(). It runs the command with arguments and returns its output as a byte string. You can decode the byte string to string using decode() function.

How do I get stdout from subprocess run?

To capture the output of the subprocess. run method, use an additional argument named “capture_output=True”. You can individually access stdout and stderr values by using “output. stdout” and “output.

What is the difference between subprocess run and subprocess Popen?

The main difference is that subprocess. run() executes a command and waits for it to finish, while with subprocess. Popen you can continue doing your stuff while the process finishes and then just repeatedly call Popen. communicate() yourself to pass and receive data to your process.

What does stdout subprocess pipe mean?

stdout=PIPE means that subprocess' stdout is redirected to a pipe that you should read e.g., using process.communicate() to read all at once or using process.stdout object to read via a file/iterator interfaces.


1 Answers

You could call .wait() on each Popen object in order to be sure that it's finished and then call log.flush(). Maybe something like this:

def run(cmd, logfile):     p = subprocess.Popen(cmd, shell=True, universal_newlines=True, stdout=logfile)     ret_code = p.wait()     logfile.flush()     return ret_code 

If you need to interact with the Popen object in your outer function you could move the .wait() call to there instead.

like image 158
Benno Avatar answered Feb 22 '23 23:02

Benno