473,386 Members | 1,720 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,386 software developers and data experts.

A better popen2

P
I've written a couple of apps that required
running a command and grabbing the output,
and I've found the existing interfaces problematic for this.

I think the proliferation of functions and classes
in the popen2 module illustrates the problem
(popen2.{popen2,popen3,popen4,Popen3,Popen4})
Now if I want to read both stdout and stderr
seperately then it's awkward to say the least
to implement that without deadlocking using
the popen2 module. Also the multiplexing of
stdout and stderr in popen4 and commands.getoutput
is not usually what one requires IMHO.

There are external solutions like the getCommandOutput recipe:
http://aspn.activestate.com/ASPN/Coo...n/Recipe/52296
which has problems that I've commented on there.
There are also very complex solutions like "subproc" from
Ken Manheimer and "task" from Rob Hooft

Therefore I bit the bullet and wrote my own,
with as simple an interface as I thought possible:
http://www.pixelbeat.org/libs/subProcess.py

Perhaps this could be included in commands.py for e.g.?

Any comments appreciated.

cheers,
Pádraig.

p.s. sorry about the previous case of trigger finger
Jul 18 '05 #1
4 1648
In article <40************@draigBrady.com>, P@draigBrady.com wrote:
....
There are external solutions like the getCommandOutput recipe:
http://aspn.activestate.com/ASPN/Coo...n/Recipe/52296
which has problems that I've commented on there.
There are also very complex solutions like "subproc" from
Ken Manheimer and "task" from Rob Hooft

Therefore I bit the bullet and wrote my own,
with as simple an interface as I thought possible:
http://www.pixelbeat.org/libs/subProcess.py

Perhaps this could be included in commands.py for e.g.?


It looks pretty good to me. A couple of minor points:

- dup2(a, sys.stdout.fileno())

You want 1, not sys.stdout.fileno(). They should be
the same, unless someone has been monkeying around
with stdout, and in that case you must use 1. (And
of course likewise with stderr and stdin, mutatis
mutando.) After the exec, whatever stdout was is
irrelevant and the new command will write to 1, read
from 0, etc.

- execvp('/bin/sh', ['sh', '-c', cmd])

I think that could be just execv(), since you've
supplied a path already. But I really prefer the
way Popen3 does it, where the input parameter is
argv, not a shell command (and you do use execvp.)
Of course you can supply ['sh', '-c', cmd] as that
parameter, but for me it's more often the case that
the parameters are already separate, and combining
them into a shell command is unnecessary and risky.
(Don't support both, like Popen3 does - that was a
mistake that seems to routinely leave people confused
about how it works.)

And I haven't really tried to verify the logic or anything,
but it does look like the right idea to me.

I will at least add it to my collection. I don't have
it at hand and haven't looked at it for a while, but
at one time I was thinking I would put together every
one of these things that has come across comp.lang.python,
might be a dozen or so but I don't think I have them all
yet. (I don't think I have "task", good find.)

The most conspicuous recent one was (I think) called
popen5, and rumor has it, will be standard with 2.4,
and will have the select functionality you need, not
only on UNIX but also on Windows, where it isn't so
trivial a feat.

Other than the platform dependency issues, I think
the main reason this wasn't in the core library from
the beginning is that the problem is more complicated
than the solution, if you know what I mean. Or, each
programmer's itch seems to be in a slightly different
place.

Donn Cave, do**@u.washington.edu
Jul 18 '05 #2
P
Donn Cave wrote:
In article <40************@draigBrady.com>, P@draigBrady.com wrote:
...
http://www.pixelbeat.org/libs/subProcess.py

Perhaps this could be included in commands.py for e.g.?

It looks pretty good to me. A couple of minor points:

- dup2(a, sys.stdout.fileno()) -> dup2(a, 1)


doh! of course. I hate magic numbers
but what I did was certainly wrong.
- execvp('/bin/sh', ['sh', '-c', cmd])

I think that could be just execv(), since you've
supplied a path already. But I really prefer the
way Popen3 does it, where the input parameter is
argv, not a shell command (and you do use execvp.)
I just copied the way Popen3 did it?
Of course you can supply ['sh', '-c', cmd] as that
parameter, but for me it's more often the case that
the parameters are already separate, and combining
them into a shell command is unnecessary and risky.
(Don't support both, like Popen3 does - that was a
mistake that seems to routinely leave people confused
about how it works.)
fair enough.
And I haven't really tried to verify the logic or anything,
but it does look like the right idea to me.

I will at least add it to my collection. I don't have
it at hand and haven't looked at it for a while, but
at one time I was thinking I would put together every
one of these things that has come across comp.lang.python,
might be a dozen or so but I don't think I have them all
yet. (I don't think I have "task", good find.)

The most conspicuous recent one was (I think) called
popen5, and rumor has it, will be standard with 2.4,
and will have the select functionality you need, not
only on UNIX but also on Windows, where it isn't so
trivial a feat.
Cool! I missed that: http://www.python.org/peps/pep-0324.html
I had a 10 second look at process.Popen.communicate() and it seems
to do much the same as I did, however it's missing a timeout
parameter like I implemented which I think is important.
Other than the platform dependency issues, I think
the main reason this wasn't in the core library from
the beginning is that the problem is more complicated
than the solution, if you know what I mean. Or, each
programmer's itch seems to be in a slightly different
place.


I aggree that the appropriate interface is hard to define
however I think we all agree that popen2 is definitely not it.

thanks a million,

Pádraig.
Jul 18 '05 #3
In article <40**************@draigBrady.com>, P@draigBrady.com wrote:
Donn Cave wrote: ....
- dup2(a, sys.stdout.fileno()) -> dup2(a, 1)


doh! of course. I hate magic numbers
but what I did was certainly wrong.


Hm, I feel like there's a lot of not-working stuff out
there because of someone's inability to get comfortable
with the UNIX system - file descriptors, ioctls, etc.
It's beautifully elegant to me. Is an arbitrary name
any better than an arbitrary number?
Cool! I missed that: http://www.python.org/peps/pep-0324.html
I had a 10 second look at process.Popen.communicate() and it seems
to do much the same as I did, however it's missing a timeout
parameter like I implemented which I think is important.
Well, I can't think of a time when I have needed it,
right off hand, but I guess when you need it, you need it.

Too bad he changed the name to "process", since from a
quick read it looks to me to support only command spawning,
not processes in general.
I aggree that the appropriate interface is hard to define
however I think we all agree that popen2 is definitely not it.


I don't know. It has some problems that generate a
regular flow of questions on comp.lang.python, but it's
useful enough for the limited range of things that are
likely to work anyway. If you want to solve a really
intractable pipe problem, see if you can get your stuff
working with what existing pty support there is in the
core distribution, for situations where the problem is
that the spawned command block-buffers its output when
talking to a pipe and the whole system deadlocks.

Where I've been motivated to write my own, the result
that I've actually used more than once has been a
sort of getstatusoutput() function, but raising an
exception instead of returning a status. Like,

try:
text = cmdmodule.invoke(cmd)
except cmdmodule.Error, value:
print >> sys.stderr, repr(cmd[0]), 'aborted:', value
sys.exit(1)

If I'm not mistaken, that's how we do things in Python,
we don't return status and expect you to check it. But
you need select to do it (because the error value comes
from unit 2.) Should be possible to build that on top
of your module, haven't tried it though.

Donn Cave, do**@u.washington.edu
Jul 18 '05 #4
On Fri, 25 Jun 2004 P@draigBrady.com wrote:
The most conspicuous recent one was (I think) called
popen5, and rumor has it, will be standard with 2.4,
and will have the select functionality you need, not
only on UNIX but also on Windows, where it isn't so
trivial a feat.


Cool! I missed that: http://www.python.org/peps/pep-0324.html
I had a 10 second look at process.Popen.communicate() and it seems
to do much the same as I did, however it's missing a timeout
parameter like I implemented which I think is important.


The current communicate() only supports a "read and write everything"
mode. communicate() won't return until all data is exchanged, and the
process is finished. In this case, I guess a timeout isn't very useful.

I've recently got in contact with Mark Pettit, which was interested in a
communicate-like method which could be called more than once. In this
case, a timeout is useful. We haven't decided on anything yet, but I've
thought about how to make this functionality available in communicate().
One idea is to add a few new keyword arguments, so that it would look
like:

def communicate(input=None, timeout=None,
all=True, linemode=False):

If all is true, then it would behave just like before. If all is false, it
will return as soon as any stdout or stderr data is available, or the
timeout has gone off. Additionally, if linemode is true, then it will
return as soon as a complete line has been read, from stdout/stderr.

Comments? Should we make a separate method instead?

(I have a patch which implements the idea above, if anyone is interested.)

Btw, the PEP is not updated yet, so anyone interested in my process.py
should look at http://www.lysator.liu.se/~astrand/popen5/ instead.

/Peter Ĺstrand <as*****@lysator.liu.se>
Jul 18 '05 #5

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

Similar topics

1
by: Guy | last post by:
Hi I was given an exstremly useful answer to a problem that I had in windows. I'm relativly new with python, but find it exstremly useful. I'm creating a script to run test files and record...
1
by: A. Lloyd Flanagan | last post by:
OK, I've got a weird one I haven't been able to figure out yet. Admittedly I haven't had time to dig into the library source, but this behavior certainly doesn't seem right. Here's a test case: ...
1
by: | last post by:
This could possibly be a bug, but I don't understand it fully so I'm posting here first. Searching the list told me other people are having this problem too. I have created a class which...
1
by: Vivien Mallet | last post by:
Hello, I use popen2.Popen4 and I experienced problems with it. Let me show you with an example. The following script is called "lines" (it prints lines of 'X'): ---------------------...
1
by: Magnus Lycka | last post by:
I'm trying to read standard out in a process started with popen2 in a non-blocking way. (Other good ways of doing this than the one I tried are appreciated.) I've tried to dumb down my code to...
9
by: Martin P. Hellwig | last post by:
Hi all, I was doing some popen2 tests so that I'm more comfortable using it. I wrote a little python script to help me test that (testia.py): --------------------------------- someline =...
3
by: mikem76 | last post by:
How do I automatically redirect stdout and stderr when using os.popen2 to start a long running process. If the process prints a lot of stuff to stdout it will eventually stop because it runs out...
1
by: Daniel Klein | last post by:
I have a few Python programs that use popen2, and they work quite nicely and dependably, so I don't really have any reason to change them to use the new subprocess module...unless of course there...
1
by: diego | last post by:
I'm trying to understand how popen2 works. Found in this group, that popen2.popen2 can cause trouble so i chose win32pipe.popen2. have a look a the listing of 2 files: ekmain.py: **************...
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
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
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
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...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...

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.