2013-10-11 20 views
12

Sto cercando di eseguire uno script di shell (non comandare) in pitone:Python: l'esecuzione di script di shell con gli argomenti (variabili), ma l'argomento non viene letta in script di shell

main.py 
------- 
from subprocess import Popen 

Process=Popen(['./childdir/execute.sh',str(var1),str(var2)],shell=True) 

execute.sh 
---------- 

echo $1 //does not print anything 
echo $2 //does not print anything 

var1 e var2 sono qualche stringa che sto usando come input per lo script di shell. Mi manca qualcosa o c'è un altro modo per farlo?

Referrals: How to use subprocess popen Python

risposta

12

Il problema è con shell=True. Rimuovere tale argomento, o passare tutti gli argomenti sotto forma di stringa, come segue:

Process=Popen('./childdir/execute.sh %s %s' % (str(var1),str(var2),), shell=True) 

La shell passerà solo gli argomenti forniti nel 1 ° argomento Popen al processo, come fa l'interpretazione di argomenti stesso . Vedere una risposta a domande simili here. In realtà, lo script della shell non ha argomenti, quindi $ 1 e $ 2 sono vuoti.

Popen erediterà stdout e stderr dallo script python, quindi di solito non c'è bisogno di fornire le stdin= e stderr= argomenti per Popen (a meno che non si esegue lo script con reindirizzamento uscita, come ad esempio >). Dovresti farlo solo se hai bisogno di leggere l'output all'interno dello script python e manipolarlo in qualche modo.

Se tutto ciò che serve è quello di ottenere l'uscita (e non la mente in esecuzione in modo sincrono), io consiglierei di provare check_output, in quanto è più facile da ottenere l'output di Popen:

output = subprocess.check_output(['./childdir/execute.sh',str(var1),str(var2)]) 
print(output) 

noti che check_output e check_call hanno le stesse regole per l'argomento shell= come Popen.

+0

Sì ... è stato utile risolto il mio problema. – creativeDrive

+0

@ user2837135 Se è stato risolto il problema, è necessario accettarlo (fare clic sul segno di spunta) e prendere in considerazione anche l'upvoting. – SethMMorton

+0

'shell = True' dovrebbe * not * essere usato in questo caso ma se lo si usa, si dovrebbe sfuggire a' var1', 'var2' usando [' shlex.quote() '] (http: //docs.python. org/3/library/shlex.html # shlex.quote): 'output = check_output (" ./ childdir/execute.sh "+" ".join (pipes.quote (str (v)) per v in [var1, var2]), shell = True) ' – jfs

3

effettivamente stanno inviando gli argomenti ... se il vostro script di shell ha scritto un file invece di stampare si dovrebbe vedere. avete bisogno di comunicare per vedere dei risultati di stampa dallo script ...

from subprocess import Popen,PIPE 

Process=Popen(['./childdir/execute.sh',str(var1),str(var2)],shell=True,stdin=PIPE,stderr=PIPE) 
print Process.communicate() #now you should see your output 
+1

Inoltre, potrebbero usare 'subprocess.call (['./ childdir/execute.sh', str (var1), str (var2)], shell = True)' se tutto ciò che vogliono fare è vedere l'output . – SethMMorton

+0

@Joran: Sono stato in grado di vedere l'output dello script della shell con shell = True, sono in grado di vedere $ 0 ('./ childdir/execute.sh') cioè lo script che si sta eseguendo, ma non gli argomenti var1, var2. – creativeDrive

+0

magari aggiungi uno shebang all'inizio dello script della shell ... potrebbe non essere in esecuzione in bash, tuttavia ti garantisco che stai inviando gli argomenti (forse gli argomenti non sono quelli che pensi che siano) –