Snippet: The leanest Popen wrapper

Phlip phlip2005 at gmail.com
Wed Aug 3 17:29:08 CEST 2011


Groupies:

This is either a code snippet, if you like it, or a request for a
critique, if you don't.

I want to call a command and then treat the communication with that
command as an object. And I want to do it as application-specifically
as possible. Anyone could think of a way to productize this:

def command(*cmdz):

    process = Popen( flatten(cmdz),
                     shell= True,
                     stdout= subprocess.PIPE,
                     stderr= subprocess.PIPE,
                     bufsize= 4096 )

    def line():
        return process.stdout.readline().rstrip()

    def s():
        while True:
            l = line()
            if not l:  break
            yield l

    line.s = s

    return line

That leads to some syntactic sugar. For example, one truly demented
way to stream in an entire block and then treat it as one big string
is this:

print '\n'.join(command('ls').s())

The point of the command() complex is the ability to start a long
command and then fetch out individual lines from it:

line = command('find', '../..')

print 'lines'
print line()
print line()
print line()

print 'all'
print list(line.s())

If you need different pipe abilities, such as stdin, you can trivially
add them to the contents of command() (it's not productized on
purpose).

So I can take the line() functor and, for example, pin it to a View
object, or put it in another thread now, right?

--
  Phlip
  http://bit.ly/ZeekLand



More information about the Python-list mailing list