Pregunta

Estoy tratando de hacer un inicio de sesión CVS de Python mediante una llamada al proceso de cvs.exe. Al llamar cvs.exe a mano, se imprime un mensaje en la consola y espera a que el usuario introduzca la contraseña.

Cuando se llama con subprocess.Popen, me he dado cuenta de que la llamada se bloquea. El código es

subprocess.Popen(cvscmd, shell = True, stdin = subprocess.PIPE, stdout = subprocess.PIPE,
    stderr = subprocess.PIPE)

Asumo que bloquea porque está a la espera de la entrada, pero mi expectativa era que llamar Popen volvería inmediatamente y entonces yo podría llamar subprocess.communicate () para introducir la contraseña real. ¿Cómo puedo lograr este comportamiento y evitar el bloqueo de Popen?

SO: Windows XP
Python: 2.6
cvs.exe: 1,11

¿Fue útil?

Solución

  • Eliminar el shell=True parte. Su cáscara tiene nada que ver con ella. Usando <=> es una causa frecuente de problemas.
  • Utilice una lista de parámetros para CMD.

Ejemplo:

cmd = ['cvs', 
       '-d:pserver:anonymous@bayonne.cvs.sourceforge.net:/cvsroot/bayonne', 
       'login']
p = subprocess.Popen(cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE) 

Esto no va a bloquear en mi sistema (mi guión continúa ejecutándose). Sin embargo, desde cvs lee la contraseña directamente desde el terminal (no de entrada o salida estándar) no pueden acaba de escribir la contraseña a la entrada estándar subproceso.

Lo que podría hacer es pasar la contraseña como parte de la especificación CVSROOT lugar, como este:

:pserver:<user>[:<passwd>]@<server>:/<path>

es decir. una función para iniciar sesión en un proyecto SourceForge:

import subprocess

def login_to_sourceforge_cvs(project, username='anonymous', password=''):
    host = '%s.cvs.sourceforge.net' % project
    path = '/cvsroot/%s' % project
    cmd = ['cvs', 
           '-d:pserver:%s:%s@%s:%s' % (username, password, host, path), 
           'login']
    p = subprocess.Popen(cmd, stdin=subprocess.PIPE, 
                              stdout=subprocess.PIPE
                              stderr=subprocess.STDOUT) 
    return p

Esto funciona para mí. Llamando

login_to_sourceforge_cvs('bayonne')

registrará en forma anónima a CVS del proyecto bayona.

Otros consejos

Si está automatizando programas externos que necesitan de entrada - como contraseña - la mejor opción probablemente sería usar pexpect .

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top