import subprocess import dataExporter #this is the script I want to run remotely import sys import os.path paths = sys.path rootPath = None for path in paths: if os.path.exists(path + "\\Maya.exe"): rootPath = path + "\\mayapy.exe" break scriptPath = dataExporter.__file__ myVar = "Hello World" command = '{0} {1} {2}'.format(rootPath, scriptPath, myVar) mayaVar = subprocess.Popen(command, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE) subprocess.Popen.wait(mayaVar) a, b = mayaVar.communicate() if mayaVar.returncode: print b else: print a
First of all, I need to give credit to Henry Foster for a wonderful post that allowed me to clarify the use of subprocess and how to get the data from it. Here is his original post.
Now I'll take a bit to clarify what I am doing in the code. The first part:
paths = sys.path rootPath = None for path in paths: if os.path.exists(path + "\\Maya.exe"): rootPath = path + "\\mayapy.exe" breakThis piece of code simply figures out where your location for mayapy.exe is. Pretty straight forward. Now for some fun stuff:
scriptPath = dataExporter.__file__ myVar = "Hello World" command = '{0} {1} "{2}"'.format(rootPath, scriptPath, myVar) mayaVar = subprocess.Popen(command, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE) subprocess.Popen.wait(mayaVar) output, errors = mayaVar.communicate() if not mayaVar.returncode: print output else: print errorsHere I am looking for the full path to the script I am going to run in the subprocess, and then initialize the subprocess itself. The "mayaVar" variable holds for us the output that that happens inside the subprocess. As you can see from the code, I am passing to the subprocess first the location of mayapy.exe, then the location of the script I want mayapy to run, and then I pass it the single variable that the script is going to accept. I also open up the PIPE from the subprocess to send and receive values between our mayapy. Then comes a rather important part of the script where I request the subprocess to wait for itself to finish the job. Now that part isnt' always necessary. However, my tool needed for the exported data to be available to continue, so I couldn't allow maya to just go on. If the wait method is not envoked, your subprocess will run just fine, but the output values from the mayaVar will not be available right away. In some cases, i.e. batch exporting, you probably don't even want to wait as you might be doing some other logic after the batch has been sent off. Keep in mind that invoking wait() will cause maya to stall and wait for the output from your subprocess and hence will not allow any user interaction during that time. Once my data is exported I check whether the process was a success at all, and if any errors were thrown. That is done via subprocess' "returncode": 1 - True, some errors have occured, 0 - False, nothing went wrong, all is good (I found this quite unintuitive at start, but got used to it). Now once your process is done, you can assign the subprocess outputs to some variables. And finally here is the actual variation of the 'dataExporter' file that can give you some sort of output:
import sys import pymel.core as pm def replyToMessage(message): reply = "" if message == "Hello World": reply = "Hello to you too!" elif message == "Goodbye": reply = "Leaving already? Ah well, take care!" else: reply = "I am sorry, not sure what you just said..." sys.stdout.write(reply) return reply if __name__ == "__main__": replyToMessage(sys.argv[1])By just importing the pymel.core you initialize a specialized maya.standalone. The 'sys.stdout.write' will write you the output that you will get back. Keep in mind, all of the feedback you get will be in string format. I do not think there is any way to pass more complex data between this script being run and the current maya session you are running as a user without any socket connection. Anyway, hope someone finds this helpful at some point! Till next time, DK