subproceso engendro que espera de entrada de consola sin el bloqueo?
-
21-08-2019 - |
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
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 .