2013-11-22 21 views
6

Ho uno script che chiama un altro script python dal sottoprocesso.Procedro modulo. Ma dal momento che ho argomenti memorizzato nella variabile (s)Passaggio di variabili a sottoprocesso.Popen

servers[server]['address'] 
servers[server]['port'] 
servers[server]['pass'] 

io sono in grado di eseguire il comando

p = subprocess.Popen(["python mytool.py -a ", servers[server]['address'], "-x", servers[server]['port'], "-p", servers[server]['pass'], "some additional command"], shell=True, stdout=subprocess.PIPE) 

Soluzione:

ho preso a lavorare con pettinatura @wilberforce & @ Risposta del ciphor ma con una piccola modifica

command = "python mytool.py -a %s -x %s -p %s some additional command" % (servers[server]['address'], servers[server]['port'], servers[server]['pass']) 
p = subprocess.Popen(command , shell=True, stdout=subprocess.PIPE) 

Cessa di funzionare se aggiungo diverse variabili tra virgolette, potrebbe richiedere al massimo "2" variabili e rompere ho aggiunto di più.

Grazie a tutti quelli che hanno risposto!

+1

Utilizzare le variabili per creare una stringa che costituisce il comando o passarle come elenco di argomenti. – beroe

risposta

5

calo shell=True. The arguments to Popen() are treated differently on Unix if shell=True:

import sys 
from subprocess import Popen, PIPE 

# populate list of arguments 
args = ["mytool.py"] 
for opt, optname in zip("-a -x -p".split(), "address port pass".split()): 
    args.extend([opt, str(servers[server][optname])]) 
args.extend("some additional command".split()) 

# run script 
p = Popen([sys.executable or 'python'] + args, stdout=PIPE) 
# use p.stdout here... 
p.stdout.close() 
p.wait() 

noti che passando per shell=True comandi con ingresso esterno è un rischio di sicurezza, come descritto da un avvertimento in the docs.

2

Quando si chiama subprocess.Popen è possibile passare una stringa o un elenco per il comando da eseguire. Se si passa una lista, gli articoli dovrebbero essere suddivisi in un modo particolare.

Nel tuo caso, è necessario dividerlo qualcosa di simile:

command = ["python", "mytool.py", "-a", servers[server]['address'], 
      "-x", servers[server]['port'], 
      "-p", servers[server]['pass'], 
      "some", "additional", "command"] 
p = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE) 

Questo perché se si passa in un elenco, Popen presuppone che hai già diviso la riga di comando in parole (i valori che avrebbero finire in sys.argv), quindi non è necessario.

Il modo in cui lo si chiama, cercherà di eseguire un binario chiamato "python mytool.py -a", che non è quello che intendevi.

L'altro modo per risolvere il problema è quello di unire tutte le parole in una stringa (che verrà quindi suddivisa in Popen - vedere subprocess.list2cmdline). Ma è meglio usare la versione elenco, se possibile - dà un controllo più semplice di come viene suddivisa la linea di comando (se gli argomenti contengono spazi o citazioni, ad esempio) senza dover cazzeggiare con i virgolette.

+0

La variabile che uso per memorizzare l'output, ma sulla stampa è vuota (che immagino non sia stata eseguita). – GaNi

+0

Penso che tu intenda questo quando leggi da p.stdout, non c'è uscita? Questo perché il comando non viene eseguito. – babbageclunk

+0

In realtà, la shell = True probabilmente sta confondendo l'acqua qui - a meno che non stiate usando globbing (per espandere un elenco di file, per esempio), è meglio spegnerlo. – babbageclunk

1

Si dovrebbe concatenare il comando per un'intera stringa:

p = subprocess.Popen("python mytool.py -a " + servers[server]['address'] + " -x " + servers[server]['port'] + " -p " + servers[server]['pass'] + " some additional command", shell=True, stdout=subprocess.PIPE) 
+0

Ho l'output salvato su variabile ma non c'è output o traccia dello script in esecuzione. potrebbe essere l'output dell'errore diretto per controllarlo? – GaNi

+0

Aggiungi "stderr = subprocess.PIPE" anche – ciphor

1

Il tuo problema nel tipo str per primo argomento Popen. Sostituirlo a list. Qui di seguito il codice può funzionare:

address = servers[server]['address'] 
port = servers[server]['port'] 
pass = servers[server]['pass'] 

command = "python mytool.py -a %s -x %d -p %s some additional command" % (address, port, pass) 
p = subprocess.Popen(command.split(), shell=True, stdout=subprocess.PIPE) 
#     ^^^^^^^^^^^^^^^ 

Inoltre si può giocare con shell, perché il sistema-dipendono parametro.

+0

Aveva il problema simile di prima, ma l'ho risolto ora. Grazie :) – GaNi

Problemi correlati