Avviare un comando shell con in uno script Python, attendere la fine e tornare allo script
-
11-07-2019 - |
Domanda
Ho uno script Python che deve lanciare un comando shell per ogni file in una directory:
import os
files = os.listdir(".")
for f in files:
os.execlp("myscript", "myscript", f)
Funziona bene per il primo file, ma dopo il " myscript " il comando è terminato, l'esecuzione si interrompe e non ritorna allo script python.
Come posso fare? Devo fork ()
prima di chiamare os.execlp ()
?
Soluzione
sottoprocesso: il modulo
sottoprocesso
ti consente di generare nuovi processi, connettersi al loro input / output / errore pipe e ottenere i loro codici di ritorno.
http://docs.python.org/library/subprocess.html
Utilizzo:
import subprocess
process = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE)
process.wait()
print process.returncode
Altri suggerimenti
Puoi utilizzare subprocess.Popen
. Ci sono alcuni modi per farlo:
import subprocess
cmd = ['/run/myscript', '--arg', 'value']
p = subprocess.Popen(cmd, stdout=subprocess.PIPE)
for line in p.stdout:
print line
p.wait()
print p.returncode
Oppure, se non ti interessa cosa fa effettivamente il programma esterno:
cmd = ['/run/myscript', '--arg', 'value']
subprocess.Popen(cmd).wait()
Il modulo di sottoprocesso è in atto dal 2008. In particolare check_call
e check_output
semplifica ulteriormente il processo di sottoprocesso. La famiglia di funzioni check_ *
è bella se sollevano un'eccezione se qualcosa va storto.
import os
import subprocess
files = os.listdir('.')
for f in files:
subprocess.check_call( [ 'myscript', f ] )
Qualsiasi output generato da myscript
verrà visualizzato come se il tuo processo abbia prodotto l'output (tecnicamente myscript
e lo script python condivida lo stesso stdout). Ci sono un paio di modi per evitarlo.
-
check_call (['myscript', f], stdout = subprocess.PIPE)
Lo stdout verrà soppresso (attenzione semyscript
produce più di 4k di output). stderr verrà comunque mostrato a meno che non si aggiunga l'opzionestderr = subprocess.PIPE
. -
check_output (['myscript', f])
check_output
restituisce lo stdout come stringa in modo che non venga visualizzato. stderr è ancora mostrato a meno che non si aggiunga l'opzionestderr = subprocess.STDOUT
.
Le funzioni os.exec * ()
sostituiscono il programma corrente con quello nuovo. Quando questo programma termina, lo stesso vale per il tuo processo. Probabilmente vuoi os.system ()
.
usa spawn
import os
os.spawnlp(os.P_WAIT, 'cp', 'cp', 'index.html', '/dev/null')
Uso os.system
import os
os.system("pdftoppm -png {} {}".format(path2pdf, os.path.join(tmpdirname, "temp")))
questo ha funzionato per me bene!
shell_command = " ls -l "
subprocess.call (shell_command.split ())