Running subprocess.call to run a Cocoa command-line application
I have one piece of Cocoa code I wrote that takes in an XML file containing bounding boxes that are then drawn on top of a video (each box has an associated frame). The Cocoa program is meant to be run from the command line (and takes in all its parameters as command line arguments)
I can run program just fine with any XML document. However, I run into problems when I try to run the program from within a Python script. For example:
with file("test.xml") as temp:
temp.write(doc.toprettyxml())
# cval is my cocoa program to call, the other 开发者_StackOverflow社区arguments are given to the Python script and parsed with optparser
command = ["./cval", "-o", options.output, "-i", str(options.interval), "-s", "%dx%d" % (options.width, options.height), "-f", str(options.frames), "-x", temp.name]
subprocess.call(command)
Sometimes this will cause my 'cval' to fail, other times not (changing one number in the XML document can change its behavior). I can also verify it's breaking when trying to read an XML element that isn't there. Only, I can open up 'test.xml', and verify the element does in fact exist.
However, if I then run 'cval' myself (outside of the Python script) with 'test.xml', it works fine. This leads me to believe that there is something strange happening when I do 'subprocess.call', but I'm not sure what it could be. I have other Cocoa/Python mixes that do completely different tasks (i.e. not using XML) that also arbitrarily exhibit weird behavior, but are more complex in nature.
I was hoping someone might have run into this problem as well, or might know the next step in debugging this weirdness.
Because the code originally used temporary files, I couldn't close the file before passing it to the subprocess. However, what I should have done instead is to flush the file before subprocess.call was invoked. The inconsistent behavior likely resulted from the size of input causing automatic flushing at different thresholds.
The code should read:
with file("test.xml") as temp:
temp.write(doc.toprettyxml())
temp.flush()
command = ["./cval", "-o", options.output, "-i", str(options.interval), "-s", "%dx%d" % (options.width, options.height), "-f", str(options.frames), "-x", temp.name]
subprocess.call(command)
Perhaps try placing a "print command" statement in there, when the return code of subprocess.call
indicates an error. On failure, see if there's any difference between what's being executed by subprocess and what you might run from the command line. Also, try calling subprocess.call(command, shell=True)
, so your command is being executed as it would in the shell (with string formatting, etc).
精彩评论