subprocesses, stdin/out, ttys, and beating insubordinate processes into the ground

Jonathan Smith smithj at rpath.com
Tue Jun 6 16:52:35 EDT 2006


First a bit about what I'm trying to do. I need a function which takes a 
patchfile and patches a source directory. Thats it. However, I need to 
be able to do so no matter what the patchlevel (-px) of the diff is. So, 
my solution is to just try to patch until it works or you try a level 
more than 3. However, if you have a reversed patch, or patch can't find 
the right file, GNU patch tries to ask for input and I don't want that. 
I know that patch will run non-interactively when backgrounded in a 
shell (no controlling tty). This is what I've tried so far:

     def patchme(self, provides, f, destDir, patchlevels):
         for patchlevel in patchlevels:
             patchArgs = ['patch', '-d', destDir, '-p%s'%patchlevel, ]
             if self.backup:
                 patchArgs.append(['-b', '-z', self.backup])
             if self.extraArgs:
                 patchArgs.append(self.extraArgs)

             log.info('attempting to patch the source with file %s and 
patchlevel %s' % (f,patchlevel))
             p1 = subprocess.Popen([provides, f], 
stdout=subprocess.PIPE, shell=False)
             p2 = subprocess.Popen(patchArgs, stdin=p1.stdout, shell=False)
             message = p2.communicate()[0] # patch seems to use stdout 
for everything, even errors

             if message != None and self.patcherror.search(message):
                 os.kill(p2.pid, signal.SIGTERM)
             elif p2.wait():
                 log.info('patch did not apply with path level %s' % 
patchlevel)
                 print message
             else:
                 return
         log.error('could not apply the patch to your build dir')


However, I still get an interactive prompt, no matter what I try! Using 
shell=False did not help, nor did trying to kill the pid if python sees 
a line from patch which isn't saying what its patching or giving info on 
a specific hunk. Any suggestions?

-smithj

PS: if you're a maintainer for GNU patch, a --non-interactive would be 
really nice ;-) (and no, -f and -t aren't good enough as they force 
other things that I don't want)



More information about the Python-list mailing list