detect suprocess interaction

Nick Craig-Wood nick at craig-wood.com
Mon Mar 26 11:30:08 CEST 2007


Robin Becker <robin at reportlab.com> wrote:
>  I'm using subprocess to carry out svn commands (probably should use the svn api 
>  package, but that's a dependency too far). Anyhow my code looks like
> 
>  from subprocess import Popen, PIPE
>  p = Popen((svn,'ls',u),stdout=PIPE,stderr=PIPE)
>  i = p.wait()
> 
>  and this sort of thing works well under most circumstances. However, when this 
>  code is executed for the very first time by a particular user it hangs waiting 
>  on user input.
> 
>  This code is being used purely for testing correctness of a particular svn url 
>  so in the normal case we want to throw away both stdout and stderr. In the 
>  exceptional case is it possible to detect that input is required and only in 
>  that case issue the current contents of stdout (presumably a request for a 
>  password)?
> 
>  Clearly I need to supply some kind of input filelike object, but is this sort of 
>  thing possible.

Yes it is possible, but if you try it you'll find you'll need to
implement the fileno() method of file objects which is asked to return
an OS file handle.  This is obviously a problem!

In general subprocess isn't really designed for interactive
processes like the above.  You'll find it much easier to use pexpect
for interactive stuff.

Note that svn has its own devious ways of finding a terminal to ask
the user for the password, eg...

$ svn ls svn+ssh://user@127.0.0.1/svn </dev/null >/dev/null 2>&1
Password: 

I don't know exactly how it does that but I suspect it is to do with
the controlling terminal...

On my system

$ setsid svn ls svn+ssh://user@127.0.0.1/svn </dev/null >/dev/null 2>&1

Pops up a gui box asking for the password!

You can simulate the above with

  Popen(..., stdin=file(os.devnull,"r"), preexec_fn=os.setsid)

-- 
Nick Craig-Wood <nick at craig-wood.com> -- http://www.craig-wood.com/nick



More information about the Python-list mailing list