Genera un sottoprocesso che prevede l'input della console senza bloccarsi?
-
21-08-2019 - |
Domanda
Sto provando a eseguire un accesso CVS da Python chiamando il processo cvs.exe.Quando si chiama cvs.exe manualmente, stampa un messaggio sulla console e quindi attende che l'utente inserisca la password.
Quando lo chiamo con subprocess.Popen, ho notato che la chiamata si blocca.Il codice è
subprocess.Popen(cvscmd, shell = True, stdin = subprocess.PIPE, stdout = subprocess.PIPE,
stderr = subprocess.PIPE)
Presumo che si blocchi perché è in attesa di input, ma la mia aspettativa era che la chiamata di Popen ritornasse immediatamente e quindi avrei potuto chiamare subprocess.communicate() per inserire la password effettiva.Come posso ottenere questo comportamento ed evitare il blocco su Popen?
Sistema operativo:Windows XP
Pitone:2.6
cvs.exe:1.11
Soluzione
- Rimuovi il
shell=True
parte.Il tuo guscio non ha niente a che fare con questo.Utilizzandoshell=True
è una causa comune di problemi. - Utilizza un elenco di parametri per cmd.
Esempio:
cmd = ['cvs',
'-d:pserver:anonymous@bayonne.cvs.sourceforge.net:/cvsroot/bayonne',
'login']
p = subprocess.Popen(cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE)
Questo non si bloccherà sul mio sistema (il mio script continua l'esecuzione).Tuttavia poiché cvs legge la password direttamente dal terminale (non dall'input o dall'output standard) tu non posso basta scrivere la password nello stdin del sottoprocesso.
Quello che potresti fare è invece passare la password come parte della specifica CVSROOT, in questo modo:
:pserver:<user>[:<passwd>]@<server>:/<path>
Cioè.una funzione per accedere a un progetto 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
Questo funziona per me.Chiamando
login_to_sourceforge_cvs('bayonne')
Accederà in modo anonimo ai cv del progetto Bayonne.
Altri suggerimenti
Se si automatizza programmi esterni che necessitano di input - come la password - la soluzione migliore sarebbe probabilmente quella di utilizzare pexpect .