Problema esecuzione di script utilizzando Python e subprocces.call eppure lavora a Bash
-
04-10-2019 - |
Domanda
Per la prima volta, chiedo un po 'di aiuto qui, come io sono più di una persona ServerFault.
sto facendo un po 'di scripting in Python e ho amare il linguaggio finora ancora ho questo piccolo problema che sta mantenendo il mio script di lavorare.
Ecco la linea di codice in questione:
subprocess.call('xen-create-image --hostname '+nom+' --memory '+memory+' --partitions=/root/scripts/part.tmp --ip '+ip+' --netmask '+netmask+' --gateway '+gateway+' --passwd',shell=True)
Ho provato la stessa cosa con os.popen. Tutte le variabili sono impostate correttamente.
Quando eseguo il comando in questione nella mia normale shell Linux, funziona perfettamente bene, ma quando eseguo usando i miei script Python, ottengo bizzarri errori. Ho anche sostituito subprocess.call () dalla funzione di stampa per assicurarsi che io sto usando l'output esatto del comando.
sono andato alla ricerca in variabili d'ambiente del mio guscio, ma sono più o meno lo stesso ... Vi posto l'errore che sto ottenendo, ma non sono sicuro che sia rilevante per il mio problema.
L'uso del valore $ linee non inizializzate [0] in sostituzione (s ///) a /usr/share/perl5/Config/IniFiles.pm linea 614. L'utilizzo di a /usr/share/perl5/Config/IniFiles.pm linea 628 non inizializzata valore $ _ nel modello di partita (m //).
Non sono un esperto di Python, quindi sono molto probabilmente manca qualcosa qui.
Grazie in anticipo per il vostro aiuto,
Antoine
Modifica
Seguendo il consiglio di miax, ho smesso di usare shell = True. Invece ho preso uno sguardo alla documentazione di Python per sottoprocesso e usato il seguente pezzo di codice :
cmd = 'xen-create-image --hostname '+nom+' --memory '+memory+' --partitions=/root/scripts/part.tmp --ip '+ip+' --netmask '+netmask+' --gateway '+gateway+' --passwd'
args = shlex.split(cmd)
subprocess.call(args)
Purtroppo, non cambia nulla ...
EDIT2
Ho usato il suggerimento dato dal miax ma ho ancora ottenere l'errore precedente ... Qui è il codice che ho usato.
cmd = ['xen-create-image', '--hostname', nom, '--memory', memory, '--partitions=/root/scripts/part.tmp', '--ip', ip, '--netmask', netmask, '--gateway', gateway, '--passwd']
subprocess.call(cmd)
Questo è davvero strano ... Il comando esatto funziona bene quando l'eseguo nel guscio regolare ...
Soluzione
La avviare lo script xen-create-image
con un hashbang? Cioè, è la prima linea di qualcosa come
#!/bin/sh
? Questa è una cosa da controllare. Un altro è che si può provare a chiamare il comando come:
cmd = ['/bin/sh', '-c', 'xen-create-image --hostname %s --memory %s --partitions=/root/scripts/part.tmp --ip %s --netmask %s --gateway %s --passwd' % (nom, memory, ip, netmask, gateway)]
subprocess.call(cmd, shell=False)
Si potrebbe desiderare di stampare cmd
per verificare questo è il comando che si intende eseguire (vale a dire controllare le sostituzioni).
Altri suggerimenti
(nella maggior parte dei casi) non vogliono utilizzare sottoprocesso con shell=True
.
Passare un elenco di argomenti del comando. Questo è il
- più sicuro:. Immaginate un utente riesce a passare
foo; rm -rf /; echo
come alcuni dei valori - più affidabile:. Immaginate una delle stringhe contiene una
$
o qualcosa - che sarà ampliato dalla shell e sostituito dal contenuto di tale variabile d'ambiente
Senza conoscere il codice e xen-create-image
, presumo che è la causa del problema.
PS: Assicurati di guardare se il codice di uscita del comando è pari a zero, e agire in modo appropriato in caso contrario. (Se si è certi che sarà sempre pari a zero, l'uso check_call
, che solleva se non lo fa;. In questo modo avrete almeno avere un comportamento definito se non riesce)
Edit2 ad esempio, che sta fallendo, è think si stanno dando le seguenti opzioni per xen-create-image
:
-
--hostname
-
--memory
-
--partitions=...
- etc
... ma in realtà si sta specificando le seguenti opzioni:
-
--hostname
spazio - spazio
--memory
spazio - spazio
--partitions=...
- etc
Hai questa riga:
cmd = ['xen-create-image', '--hostname ', nom, ' --memory ', memory, ' --partitions=/root/scripts/part.tmp', ' --ip ', ip, ' --netmask ', netmask, ' --gateway ', gateway, ' --passwd']
Ma è necessario togliere gli spazi in più:
cmd = ['xen-create-image', '--hostname', nom, '--memory', memory, '--partitions=/root/scripts/part.tmp', '--ip', ip, '--netmask', netmask, '--gateway', gateway, '--passwd']
È necessario print
il comando che si sta utilizzando:
cmd = 'xen-create-image --hostname '+nom+' --memory '+memory+' --partitions=/root/scripts/part.tmp --ip '+ip+' --netmask '+netmask+' --gateway '+gateway+' --passwd'
print "COMMAND:", cmd
E quindi incollare il comando nella vostra shell per assicurarsi che è esattamente la stessa.