cooler piping

C

Csaba Henk

For me, one reason for using Python is that with the help of it
I can rid of several problems that I faced with during writing scripts
in Bourneish shells. Biggest of these problem was the quotation madness
stemming from the typelessness of the shell language.

When using Python as a shell replacement I often launch apps from Python and
use different piping constructs to pass data to/get data from these apps. I
expect from the language that I could perform these actions simply and
effectively.

However, its not the case: there is os.pipe() which is low-level and its
usage is complex, and there are several popen functions which are simple to
use, but they evaluate the given command by passing it to the shell,
throwing me back to the middle of the quotation hell I want to escape from.
A typical case is when one tries to find out some info about a file by
invoking the "file" command on it: the name of the file can be (almost)
anything, thus doing os.popen("file " + filename) gets sucked easily (here
filename is a variable storing the name of the file). (Don't tell me there
is a module in Python with the fucntionality of the file command [I don't
know wheter is], I could find out many similar examples.) What would be cool
is having a function with an execvp-like syntax: if I could do something
like os.fancypopen('file', ['file',fname])...

Considering me, I came over this problem by using the following module:

<code>
import os
import sys

def fancypopen(fname,args):
pfd = os.pipe()
if os.fork() == 0:
os.close(pfd[0])
os.dup2(pfd[1],sys.stdout.fileno())
os.execvp(fname,args)
else:
os.close(pfd[1])
return os.fdopen(pfd[0],'r')

def fancypopen2(fname,args):
pfdout = os.pipe()
pfdin = os.pipe()
if os.fork() == 0:
os.close(pfdout[0])
os.dup2(pfdout[1],sys.stdout.fileno())
os.close(pfdin[1])
os.dup2(pfdin[0],sys.stdin.fileno())
os.execvp(fname,args)
else:
os.close(pfdout[1])
os.close(pfdin[0])
return (os.fdopen(pfdin[1],'w'),os.fdopen(pfdout[0],'r'))

sfancypopen = lambda f,a: fancypopen(f, [f] + a)
sfancypopen2 = lambda f,a: fancypopen2(f, [f] + a)
</code>

Now my question is that shouldn't (doesn't) Python include a *standard*
module like this? That wouldn't be much hassle but would improve the
usability of the language...


--
Csaba

"There's more to life, than books, you know but not much more..."
[The Smiths]
***
If you want to send me a mail, see it in the mailto link at
http://www.renyi.hu/~ekho/egyelore.html
 
D

Donn Cave

Quoth Csaba Henk <csaba@phony_for_avoiding_spam.org>:
....
| However, its not the case: there is os.pipe() which is low-level and its
| usage is complex, and there are several popen functions which are simple to
| use, but they evaluate the given command by passing it to the shell,
| throwing me back to the middle of the quotation hell I want to escape from.
| A typical case is when one tries to find out some info about a file by
| invoking the "file" command on it: the name of the file can be (almost)
| anything, thus doing os.popen("file " + filename) gets sucked easily (here
| filename is a variable storing the name of the file). (Don't tell me there
| is a module in Python with the fucntionality of the file command [I don't
| know wheter is], I could find out many similar examples.) What would be cool
| is having a function with an execvp-like syntax: if I could do something
| like os.fancypopen('file', ['file',fname])...

You may find that popen2.popen2() already comes pretty close to this.
You may specify a command string, but you also may specify a list of
strings for execvp. The only difference is that you supply only the
argument list, and the file to execute is inferred from its first element.

Donn Cave, (e-mail address removed)
 
C

Csaba Henk

Quoth Csaba Henk <csaba@phony_for_avoiding_spam.org>:
...
| is having a function with an execvp-like syntax: if I could do something
| like os.fancypopen('file', ['file',fname])...

You may find that popen2.popen2() already comes pretty close to this.
You may specify a command string, but you also may specify a list of
strings for execvp. The only difference is that you supply only the
argument list, and the file to execute is inferred from its first element.

Thanks, it's cool! Just what I needed... Now I checked, I can pass a list of
strings to os.popen2(), too.

Only if documentation didn't suck... The Library Reference doesn't mention
anything about the type of the cmd argument of the popen functions, and
after I saw the function working with a cmd of type string, I automatically
assumed that it can be nothing else but a string. (And I don't blame myself
for this...)

--
Csaba

"There's more to life, than books, you know but not much more..."
[The Smiths]
***
If you want to send me a mail, see it in the mailto link at
http://www.renyi.hu/~ekho/egyelore.html
 
D

Donn Cave

Quoth Csaba Henk <csaba@phony_for_avoiding_spam.org>:
....
| Only if documentation didn't suck... The Library Reference doesn't mention
| anything about the type of the cmd argument of the popen functions, and
| after I saw the function working with a cmd of type string, I automatically
| assumed that it can be nothing else but a string. (And I don't blame myself
| for this...)

Well, you will see a lot of it in Python, functions whose arguments may
be of various types. Not polymorphic, because we're not talking about
any semantic overlap between the types - this is more like overloading.

I personally feel that it's a sloppy practice that leads to confusion
and errors, but I've done it myself, so at least you and I can use this
example as a reminder of what not to do.

Donn Cave, (e-mail address removed)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,774
Messages
2,569,598
Members
45,152
Latest member
LorettaGur
Top