7

Question: Is there a way, using Python, to access the stdout of a running process? This process has not been started by Python.

Context: There is a program called mayabatch, that renders out images from 3D Maya scene files. If I were to run the program from the command line I would see progress messages from mayabatch. Sometimes, artists close these windows, leaving the progress untracable until the program finishes. That led me along this route of trying to read its stdout after it's been spawned by a foreign process.

Background:

  • OS: Windows 7 64-bit

My research so far: I have only found questions and answers of how to do this if it was a subprocess, using the subprocess module. I also looked briefly into psutil, but I could not find any way to read a process' stdout.

Any help would be really appreciated. Thank you.

kartikg3
  • 2,590
  • 1
  • 16
  • 23
  • 2
    You could use a socket with a pre-known port, and pipe output to it if connected, no? – MeetTitan Dec 19 '14 at 20:29
  • 1
    Using native OS services -- this is going to be a challenge and will be entirely dependant on what OS you are using. But it sounds like the problem is simpler than that. It sounds like `mayabatch` has a mechanism to tell you the status of already running programs...and it sounds like it's a command line utility. Why just script it's execution and parse it's output? – user590028 Dec 19 '14 at 20:30
  • 1
    On Linux you can (sort of) do this with `strace`. Perhaps there is a Windows equivalent? – jme Dec 19 '14 at 21:04
  • Thanks for all your inputs. They were very useful. – kartikg3 Dec 20 '14 at 14:37

1 Answers1

6

I don't think you can get to the stdout of a process outside of the code that created it

The lazy way to is just to pipe the output of mayabatch to a text file, and then poll the text file periodically in your own code so it's under your control, rather than forcing you to wait on the pipe (which is especially hard on Windows, since Windows select doesn't work with the pipes used by subprocess.

I think this is what maya does internally too: by default mayaBatch logs its results to a file called mayaRenderLog.txt in the user's Maya directory.

If you're running mayabatch from the command line or a bat file, you can funnel stdout to a file with a > character:

  mayabatch.exe "file.ma" > log.txt

You should be able to poll that text file from the outside using standard python as long as you only open it for reading. The advantage of doing it this way is that you control the frequency at which you check the file.

OTOH If you're doing it from python, it's a little tougher unless you don't mind having your python script idled until the mayabatch completes. The usual subprocess recipe, which uses popen.communicate() is going to wait for an end-of-process return code:

 test = subprocess.Popen(["mayabatch.exe","filename.mb"], stdout=subprocess.PIPE)
 print test.communicate()[0]

works but won't report until the process dies. But you calling readlines on the process's stdout will trigger the process and report it one line at a time:

 test = subprocess.Popen(["mayabatch.exe","filename.mb"], stdout=subprocess.PIPE)
 reader = iter(test.subprocess.readlines, "")
 for line in reader:
     print line

More discussion here

Community
  • 1
  • 1
theodox
  • 12,028
  • 3
  • 23
  • 36