473,385 Members | 1,569 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,385 software developers and data experts.

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

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)

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

Apr 18 '06 #1
4 2596
On 18 Apr 2006 01:37:03 -0700, rumours say that "jelle"
<je**********@gmail.com> might have written:
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.


[snip]

Overload the __or__ special function (ie the 'pipe' operator) instead of the
__gt__ operator.

I remember I have seen such a proposition (mentioning pump, filters and
sinks) but I couldn't find it in google.groups.com --I think Aahz had
something to do with it, but ICBW.

Ah, I found it:

http://mail.python.org/pipermail/pyt...il/044205.html

I don't know why I remembered Aahz about it :)

Check this too:

http://groups.google.gr/group/comp.l...7efd4d3aa490ed
--
TZOTZIOY, I speak England very best.
"Dear Paul,
please stop spamming us."
The Corinthians
Apr 18 '06 #2
Hi Christos,

Thanks for your pointers there, impressive to see
-that a 12 year old thread still can make an interesting read
-you being able to remember & trace it... impressive...

Thanks for your pointers.
I think the
input > process > output
Syntax is more powerful , since it would let you build chaining
commmands in a more readable fashion.

The goal of this class would be to construct command chains such as:

input > processA | processB > ouput

Something which wouldn't be possible if only one operator is
overloaded.
I'm curious to see if its doable via overloading, since no __rgt__
methods exists...

Apr 18 '06 #3
On 18 Apr 2006 05:00:55 -0700, rumours say that "jelle"
<je**********@gmail.com> might have written:
Hi Christos,

Thanks for your pointers there, impressive to see
-that a 12 year old thread still can make an interesting read
-you being able to remember & trace it... impressive...

Thanks for your pointers.
I think the
input > process > output
Syntax is more powerful , since it would let you build chaining
commmands in a more readable fashion.

The goal of this class would be to construct command chains such as:

input > processA | processB > ouput

Something which wouldn't be possible if only one operator is
overloaded.
I'm curious to see if its doable via overloading, since no __rgt__
methods exists...


The problem with the operators chaining is that ">" is treated differently
than "|". Check the following disassembly:
import dis
dis.dis(compile("a<b<c", "", "eval"))
0 0 LOAD_NAME 0 (a)
3 LOAD_NAME 1 (b)
6 DUP_TOP
7 ROT_THREE
8 COMPARE_OP 0 (<)
11 JUMP_IF_FALSE 10 (to 24)
14 POP_TOP
15 LOAD_NAME 2 (c)
18 COMPARE_OP 0 (<)
21 JUMP_FORWARD 2 (to 26) 24 ROT_TWO 25 POP_TOP 26 RETURN_VALUE
dis.dis(compile("a|b|c", "", "eval"))

0 0 LOAD_NAME 0 (a)
3 LOAD_NAME 1 (b)
6 BINARY_OR
7 LOAD_NAME 2 (c)
10 BINARY_OR
11 RETURN_VALUE
The comparison operators include some logic in order to "do what I mean" (so
that 4<x<10 works like 4<x and x<10, but x<10 will never be evaluated if 4<x
is False), and that is why I suggested you use the "|" operator instead.

Of course, you can use the ">" operator, just don't chain it, in order to
avoid such unexpected behaviour.
--
TZOTZIOY, I speak England very best.
"Dear Paul,
please stop spamming us."
The Corinthians
Apr 19 '06 #4
jelle wrote:
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!


How about good old function call?

A = Lines('inputString')
B = Process('process.exe')
C = Process('proc2.exe')
result = pipeline(A, B, C, Lines()) # Text result
result = pipeline(A, B, C, Bytes()) # Binary result
pipeline(A, B, C, file("somefile","wb")) # dump to binary file

Apr 19 '06 #5

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

12
by: km | last post by:
hi all, can any linux command be invoked/ executed without using shell (bash) ? what abt security concerns ? regards, KM
0
by: Tom Brown | last post by:
I need to chain together three linux commands and get the final output. I read the documentation for Popen in the subprocess module for replacing the shell pipe line. I followed the example and...
10
by: A.M | last post by:
Hi, I am having difficulty with shell scripting in Python. I use the following command to run a DOS command and put the return value in a Python variable:
2
by: Jeremy Moles | last post by:
I'm not sure if this is really the right place to ask this question, but since the implementation is in Python, I figured I'd give it a shot. I want to "wrap" a shell process using popen inside...
7
by: Bin Chen | last post by:
Hi, I want to do following: get a user input regex, then pass this as a parameter to grep, and then get the result from grep. Any code snip to implement the similar function? I am a python...
2
by: Gerard Flanagan | last post by:
Hello, I have a third party shell script which updates multiple environment values, and I want to investigate (and ultimately capture to python) the environment state after the script has run....
3
by: George Sakkis | last post by:
I'm trying to figure out why Popen captures the stderr of a specific command when it runs through the shell but not without it. IOW: cmd = if 1: # this captures both stdout and stderr as...
1
by: raocheng | last post by:
Please see the following code. Suppose I have many shell commands to be executed. And I don't want to fork a sub shell for each command(eg: status,output = commands.getstatusoutput(cmd)) because...
7
by: Samuel A. Falvo II | last post by:
I have a shell script script.sh that launches a Java process in the background using the &-operator, like so: #!/bin/bash java ... arguments here ... & In my Python code, I want to invoke...
1
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome former...
0
by: ryjfgjl | last post by:
In our work, we often need to import Excel data into databases (such as MySQL, SQL Server, Oracle) for data analysis and processing. Usually, we use database tools like Navicat or the Excel import...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.