[Tutor] Using os.spawn commands

Danny Yoo dyoo@hkn.eecs.berkeley.edu
Tue, 12 Feb 2002 00:23:32 -0800 (PST)

On Sat, 9 Feb 2002, Sheila King wrote:

> I wanted to write a script to test this other script of mine. I
> thought one of the os.spawn commands would be best, so that if one of
> the test processes crashed, at least my testing script wouldn't? (That
> is correct thinking there, right?)

[Warning: this message is extremely long, and very windy.  I'm trying to
show the steps and missteps I'm taking as I'm trying to solve this... and
in the end, I'm not even sure I'm answering the right quetsion.  *grin*.]

Hi Shelia,

Has anyone answered you on this yet?  I've never personally played with
the spawn functions before either.  Ok, let me take a look... I wonder
what google will say.


Arg!  Wrong Spawn!  *grin*

Ok, I'm taking a closer look at:


> and the following  command executes from within that directory from a
> command line prompt (in a DOS window):
> E:\Web\Thinkspotwebsite\dev>python email_filter.py < test4.txt
> and gives me the expected results.

Hmmm... But I'm not quite sure what will happen on a stdin redirection ---
I don't believe the system literally treats '< test4.txt', as a set of
arguments, but actually does some low-level things to set up standard
input appropriately.  Let's try a simple example with spawnl() and get
that working first.

Let's say that we have the following test program called 'greet.py':

## This is "greet.py".
import sys
print "Hello HAL."
print "The sys.argv is", sys.argv
print "What is the password? "
passwd = raw_input()
if passwd == 'open':
    print "ok"
    print "no"

Here's our first unsuccessful attempt at getting this to work:

>>> os.spawnl(os.P_WAIT, 'python', 'python', 'greet.py')  

The error code "127" means that the system can't find the exectuable; this
is equivalent to what you're running into with that OSError.

> Traceback (most recent call last):
>   File "<pyshell#3>", line 1, in ?
>     os.spawnl(os.P_WAIT, 'python email_filter.py < test4.txt')
>   File "E:\PYTHON\PYTHON22\lib\os.py", line 530, in spawnl
>     return spawnv(mode, file, args)
> OSError: [Errno 2] No such file or directory

It looks like we really do need to put the absolute pathname in here:

>>> os.spawnl(os.P_WAIT, '/usr/bin/python', 'python', 'greet.py')
Hello HAL.
The sys.argv is ['greet.py']
What is the password? 

The '0' comes as the return value of the spawnl() call.  Ok, so that
appears to work as long as we're not doing any tricky redirection.

At the moment, I'm somewhat stumped about doing this redirection nicely...
Let's see...  The thing that I'm worried about is that simply redirection
'sys.stdin' doesn't work:

>>> from StringIO import StringIO
>>> source = StringIO()
>>> source.write("abracadabra!\n")
>>> source.seek(0)
>>> sys.stdin = source
Hello HAL.
The sys.argv is ['greet.py']
What is the password? 
blah                         ## I actually had to enter things at this
                             ## point

There's a reason for this: Python is actually doing a lot of indirect
stuff when we set sys.stdin, and this indirection doesn't quite work on
spawn stuff.  The documentation sorta hints at this in


We can truly redirect stdin by doing some trickery:

def redirectStdin(filename):
    """We're trying to really redirect the true standard input here."""
    fd = os.open(filename, os.O_RDONLY)
    os.dup2(fd, sys.stdin.fileno())

So if we do something like this:

os.spawnl(os.P_WAIT, '/usr/bin/python', 'python', 'email_filter.py')

I think this may work --- you might need to readjust the call to
'/usr/bin/python' to what Windows expects.  However, now I don't know how
to get stdin to go back to the keyboard.  *laugh*  Oiii!

I get the feeling this is all too much work: is it possible to just use
os.system() instead?