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

È stato utile?

Soluzione

  • Rimuovi il shell=True parte.Il tuo guscio non ha niente a che fare con questo.Utilizzando shell=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 .

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top