Category Archives: Osx

Terminating a child process from python

fixing a problem with calling 3rd party applications as subprocesses

I’ve been working on improving my renderfarm, and I’ve run into some trouble trying to close clients remotely. You can easily end a python process with sys.exit(), however if a rendering application (say Nuke) has been spawned by the script, it will not close. After some digging (and a bunch of great help from stackOverflow) I seem to have come up with a solution. When you call a 3rd party application with either call() or:

process = Popen(allRenderArg, env=os.environ)

Python will create a tiny, dummy process which only exists to call that application. When you exit your script, python will clean up those dummy processes, but won’t kill child processes, thereby leaving the renders going.

The solution that I’ve come up with is to get the pid of those dummy python processes, then use some unix commands to find the pids of their children, and kill them with os.kill(). If this was a linux platform I could do it in a more efficient way (possibly using pstree) but on OSX I have to use grep and some fancy code:

processId = process.pid
print "attempting to terminate "+str(processId)
command = " ps -o pid,ppid -ax | grep "+str(processId)+" | cut -f 1 -d \" \" | tail -1"
ps_command = Popen(command, shell=True, stdout=PIPE)
ps_output = ps_command.stdout.read()
retcode = ps_command.wait()
assert retcode == 0, "ps command returned %d" % retcode
print "child process pid: "+ str(ps_output)
os.kill(int(ps_output), signal.SIGTERM)
os.kill(int(processId), signal.SIGTERM)

There might be a nicer way, but I don’t know it.

OSX Paths, X11 and paths.d

part rant, part fix to an obnoxious bug: "1/bin"

If you’re working with a renderer from the command line, you’ll often need the location of that renderer in the path, so you can call it easily (without always needing the full path). On OSX, there is a folder paths.d under /etc, where you can place text files that will contain paths to be appended to $PATH in terminal sessions:

/etc/paths.d/Nuke6.3v8 contents:

/Applications/Nuke6.3v8/Nuke6.3v8.app/Contents/MacOS

This morning I was attempting to add some other versions to the path (7.0v1, 7.0v6) and I was running into some ridiculous errors. When I added another file:

/etc/paths.d/Nuke7.0v1 contents:

/Applications/Nuke7.0v1/Nuke7.0v1.app/Contents/MacOS
what I got in my path was instead
/Applications/Nuke7.0v1/Nuke7.0v1.app/Contents/MacOS1/bin

Why? I have no idea. I tried different file names, different text encoding types, etc and was always getting that extra text on the end. I noticed that I had one other file in my paths.d, from the installation of the osx developer tools: 50-X11. When I removed that file, everything worked! However, I want to keep that in my path (not sure what apps might be there), so I renamed it to x11 and now that extra text is gone.

I hope this helps someone else in the same situation. I don’t understand what macintosh is doing half the time, and this is that half.