Working with Python subprocess
jimmyg.org
jimmyg.org
https://github.com/kennethreitz/envoy
For reference, he's the same guy that did the Requests module, which is pretty much the defacto standard for avoiding urllib hell.
I would guess that subprocess is so ugly just because it needs to be so flexible. Personally, I don't find it so offensive, mostly because I have to take advantage of its "warts" on almost a daily basis.
p.communicate() only works if the output of the program can fit in memory. If it can't, python will gladly crash your box for you.
The buffer size of the os pipes on Linux are 64k. If you don't do your reads and writes in this size, it's possible to deadlock yourself.
Reads on the pipes has to be done in a non-blocking fashion, using os.read(), if you're dealing with streams of data that are larger than the memory you have available to yourself.
You can chain multiple subprocesses together directly, if you feed the stdout pipe to stdin on the next process.
p1 = subprocess.Popen(['cat', 'foo'], stdout=subprocess.PIPE)
p2 = subprocess.Popen(['grep', 'cat'], stdin=p1.stdout, stdout=subprocess.PIPE)
p2.communicate()
select.poll() works on the os.pipes which are contained in the Popen objects.Likewise compare it to the perl syntax that does the same thing (and happens to look at lot like the shell does, with good reason).
Python is a great language, but sometimes the aesthetic taste of its adherents just boggles me.
Edit: I see Pewpewarrows above pointing out that there's a third party module which fixes some of the nonsense in subprocess. And indeed, it looks fairly clean at first glance. So perhaps I should retract my blanket condemnation of its adherents' taste.
But we've been seeing a lot of random several-year-old python stuff on Hacker News for quite a while now. Can't someone just post a link to a comprehensive list of all python tutorials, rather than them all being submitted individually like this?
All of that is the kind of thing that makes Python people's blood boil, of course, but it's absolutely the reason that regex handling is just so much natural in perl.
I use subprocess on nearly a daily basis to automate database actions, and while the api is not the most appealing, it actually does its job very well, letting me coordinate 2-3 processes in a chain that's moving 100's of gigs of data on a regular basis.
Another easy way to get a returncode without polling is to call communicate().
returncode will be set when it returns from communicate().