Shell like syntax for subprocess.Popen # overloading >, <, |

jelle jelleferinga at gmail.com
Tue Apr 18 04:37:03 EDT 2006


Hi,

I use python quite a bit to couple different programs together.
Doing so has been a _lot_ easier since subprocess came around, but
would really like to be able to use the succinct shell syntax; >, <, |

That really shouldn't be too hard to wrap in a class, but so far I
didn't succeed to do so this well, since I'm facing some trouble with
operator precedence that I do not know how to overcome.

Consider the following:

A = 'inputString'
B = Process('process.exe')
C = cStringIO.StringIO() # output bucket

A > B > C

A is being piped to B and processed, but the output of B is not being
piped to C
executing A > B; B > C works as expected however.
Which is disappointing, since what I'm trying to achieve is a sugar
syntax for Popen processes, where directly sees the chain of
commands...

Any suggestions to overcome this issue are greatly appreciated!

cheers,
 -jelle

-------------------------------------------------------------------------
class Process(Popen, object):
    def __init__(self, commandString, wait=False):
        assert isinstance(commandString, str)
        cmd         = commandString.split()

        self.cmd    = commandString
        self.exe    = cmd.pop(0)
##        self.args   = cmd

        self.process = Popen(self.cmd, shell=True, stdin=PIPE,
stdout=PIPE, close_fds=False)

        self.stdout = self.process.stdout
        self.stderr = self.process.stderr

    def __repr__(self):
        return 'Process instance ( %s ) ' % (self.exe)

    def __or__(self, other):     # PIPE
        '''
        returns the output of Process A -> Process B
        takes a Process instance as argument
        '''
        assert isinstance(other, Process), '%s\n is not a Process
instance' % (other)
        print 'PIPE'
        self > other


    def __lt__(self, other):     # STDIN
        '''
        takes a StringIO, file or string objectas argument
        '''
        print '>'
        print 'STDIN'
        if isinstance(other, str):
            self.process.communicate(other)
        else:
            self.stdout, self.stderr =
self.process.communicate(other.read())
            self.process.wait()

    def __gt__(self, other):     # STDOUT
        '''
        takes a StringIO, file or string object as argument
        returns the result of an external process
        '''
        print '<'
        print 'STDOUT'
        assert hasattr(other, 'write') or isinstance(other, str)
        if isinstance(other, str):
            other += self.stdout
        else:
            other.write(self.stdout)

-------------------------------------------------------------------------




More information about the Python-list mailing list