From: Michael Torrie on
On 06/28/2010 05:48 AM, Dave Pawson wrote:
> Main queries are: Ease of calling out to bash to use something like
> imageMagick or Java? Ease of grabbing return parameters? E.g. convert
> can return both height and width of an image. Can this be returned to
> the Python program? Can Python access the exit status of a program?

Sure. I've created a module called runcmd that does 90% of what I want
(easy access to stdout, stderr, error code). I've attached it to this
e-mail. Feel free to use it; this post puts my code into the public domain.

> I'd prefer the advantages of using Python, just wondering if I got so
> far with the port then found it wouldn't do something?

Python really isn't a shell scripting language. So there are things
that Bash does much better, such as spawning processes and piping them
together. I've tried over the years to create a pythonic library that
would let me do that, but haven't found a good syntax that I like.

It turns out, though, that much of what I use piping for in Bash is to
run external processes to do things that I could use python modules for.
For example, I typically pipe stuff to cut a lot to get certain fields.
For example:

ps ax | cut -c1-5

In python I could simply take the output of "ps ax" and use python's
own, superior, cutting routines (using my module):

(err, stdout, stderr) = runcmd.run( [ 'ps', 'ax' ] )
for x in stdout.split('\n'):
print x.strip().split()[0]

Sure it's a couple more lines in this case, but in other cases, python's
abilities make it simpler than bash. A great document on how you can
exploit python's abilities (particularly generators) to replace bash
pipelines is here: http://www.dabeaz.com/generators/




From: John Nagle on
On 6/28/2010 7:58 AM, Benjamin Kaplan wrote:
> How does a program return anything other than an exit code?

Ah, yes, the second biggest design mistake in UNIX.

Programs have "argv" and "argc", plus environment variables,
going in. So, going in, there are essentially subroutine parameters.
But all that comes back is an exit code. They should have had
something similar coming back, with arguments to "exit()" returning
the results. Then the "many small intercommunicating programs"
concept would have worked much better.

C was like that once. In the 1970s, all you could return was
an "int" or a "float". But that got fixed.

John Nagle
From: Dave Pawson on
On 28 June 2010 18:39, Michael Torrie <torriem(a)gmail.com> wrote:
> On 06/28/2010 05:48 AM, Dave Pawson wrote:
>> Main queries are: Ease of calling out to bash to use something like
>> imageMagick or Java? Ease of grabbing return parameters? E.g. convert
>> can return both height and width of an image. Can this be returned to
>> the Python program? Can Python access the exit status of a program?
>
> Sure.  I've created a module called runcmd that does 90% of what I want
> (easy access to stdout, stderr, error code).  I've attached it to this
> e-mail.  Feel free to use it; this post puts my code into the public domain.

Thanks Michael.

>
>> I'd prefer the advantages of using Python, just wondering if I got so
>> far with the port then found it wouldn't do something?
>
> Python really isn't a shell scripting language.  So there are things
> that Bash does much better, such as spawning processes and piping them
> together.  I've tried over the years to create a pythonic library that
> would let me do that, but haven't found a good syntax that I like.

I'm using xml quite a bit and tried xmlsh which does the job but has
what I think of as irregular syntax?
Bash is fine for smaller scripts, but I had to be really careful by
the time I got to around 1200 loc. Hence my preference for Python.



>
> It turns out, though, that much of what I use piping for in Bash is to
> run external processes to do things that I could use python modules for.

I kept thinking that.. Then I had to use Java/Python for some plain
old calculations, so it kept nagging me that a cleaner approach
would be a single language.


> Sure it's a couple more lines in this case, but in other cases, python's
> abilities make it simpler than bash.  A great document on how you can
> exploit python's abilities (particularly generators) to replace bash
> pipelines is here:  http://www.dabeaz.com/generators/

Thanks for the reference.

I'm nearly there with the mix of return codes and output values,
using subprocess.

p1 = subprocess.Popen(['identify', '-format' , '%[fx:w]' , f ],
stdout=subprocess.PIPE)
resp1= p1.communicate()
#print dir(p1)
p2 = subprocess.Popen(['identify', '-format' , '%[fx:h]' , f ],
stdout=subprocess.PIPE)
resp2= p2.communicate()
if (p1.returncode or p2.returncode):
print "Error ",p1.returncode
sys.exit(2)
else:
width=int(resp1[0])
height=int(resp2[0])

print "Height %s, width %s " % (height, width)

Not happy with the error handling yet, but this was the bit
that I thought I'd struggle with.

regards


--
Dave Pawson
XSLT XSL-FO FAQ.
Docbook FAQ.
http://www.dpawson.co.uk
From: Michael Torrie on
On 06/28/2010 12:05 PM, Dave Pawson wrote:
> On 28 June 2010 18:39, Michael Torrie <torriem(a)gmail.com> wrote:
>
>> Sure. I've created a module called runcmd that does 90% of what I
>> want (easy access to stdout, stderr, error code). I've attached
>> it to this e-mail. Feel free to use it; this post puts my code
>> into the public domain.
>
> Request please Michael.
>
> Examples of usage in the docstring?

Well the simplest form is as I showed in my e-mail:

(err,stdout,stderr) = runcmd.run (['command','arg1','arg2', ... ])

An example where you need to pass stdin:

input="some string\n"
(err,stdout,stderr) = runcmd.run (['cmd','arg1',], stdin=input)

err is the return error code (int) and stdout and stderr are the strings
the result from the process's output, both strings.

There are some other features (or bugs probably) that you can get from
the source code itself. I think at one time I wanted to be able to have
callbacks that would do something with stdout and stderr (in a
real-time, unbuffered way), but I have never used them and don't think
they work.
From: Paul Rubin on
John Nagle <nagle(a)animats.com> writes:
> Programs have "argv" and "argc", plus environment variables,
> going in. So, going in, there are essentially subroutine parameters.
> But all that comes back is an exit code. They should have had
> something similar coming back, with arguments to "exit()" returning
> the results. Then the "many small intercommunicating programs"
> concept would have worked much better.

That's interesting but I'm having a hard time seeing how it would work.
I think environment variables didn't exist in early versions of Unix,
and argc/argv were passed to the child process on its stack. I guess
the reverse side could involve the "wait" system call taking a callback
parameter with a buffer to receive the returned data. But that still
only happens when the child actually exits, and presumably
intercommunicating netween programs should be bidirectional. But Unix
has always had pipes for that.