J'ai donc remarqué subprocess.call
en attendant que la commande se termine avant de poursuivre avec le script python, je n'ai aucun moyen d'obtenir la sortie standard, sauf avec subprocess.Popen
. Existe-t-il des appels de fonction alternatifs qui attendraient la fin? (J'ai aussi essayé Popen.wait
)
REMARQUE: j'essaie d'éviter os.system
appel
result = subprocess.Popen([commands...,
self.tmpfile.path()], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
out, err = result.communicate()
print out+"HIHIHI"
ma sortie:
HIHIHI
REMARQUE: j'essaie d'exécuter wine
avec cela.
J'utilise la construction suivante, bien que vous souhaitiez peut-être éviter Shell=True
. Cela vous donne la sortie et le message d'erreur pour toute commande, ainsi que le code d'erreur:
process = subprocess.Popen(cmd, Shell=True,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
# wait for the process to terminate
out, err = process.communicate()
errcode = process.returncode
subprocess.check_output(...)
appelle le processus, déclenche si son code d'erreur est différent de zéro et renvoie sinon sa sortie standard. C'est juste un raccourci rapide pour que vous n'ayez pas à vous soucier des PIPE
et des choses.
Si votre processus donne un stdout énorme et pas de stderr, communicate()
pourrait être la mauvaise façon de procéder en raison de restrictions de mémoire.
Au lieu,
process = subprocess.Popen(cmd, Shell=True,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
# wait for the process to terminate
for line in process.stdout: do_something(line)
errcode = process.returncode
pourrait être la voie à suivre.
process.stdout
Est un objet de type fichier que vous pouvez traiter comme tout autre objet de ce type, principalement:
read()
à partir de celui-cireadline()
etCe dernier est ce que je fais ci-dessus afin d'obtenir son contenu ligne par ligne.
J'essaierais quelque chose comme:
#!/usr/bin/python
from __future__ import print_function
import shlex
from subprocess import Popen, PIPE
def shlep(cmd):
'''shlex split and popen
'''
parsed_cmd = shlex.split(cmd)
## if parsed_cmd[0] not in approved_commands:
## raise ValueError, "Bad User! No output for you!"
proc = Popen(parsed_command, stdout=PIPE, stderr=PIPE)
out, err = proc.communicate()
return (proc.returncode, out, err)
... En d'autres termes, laissez shlex.split () faire la plupart du travail. Je n'essaierais PAS d'analyser la ligne de commande de Shell, de trouver des opérateurs de tuyaux et de configurer votre propre pipeline. Si vous allez faire cela, vous devrez essentiellement écrire un analyseur syntaxique complet de Shell et vous finirez par faire beaucoup de plomberie.
Bien sûr, cela soulève la question, pourquoi ne pas simplement utiliser Popen avec l'option Shell = True (mot-clé)? Cela vous permettra de passer une chaîne (pas de fractionnement ni d'analyse) au shell et de rassembler les résultats à gérer comme vous le souhaitez. Mon exemple ici ne traitera pas les pipelines, les raccourcis, la redirection des descripteurs de fichiers, etc. qui pourraient être dans la commande, ils apparaîtront tous comme des arguments littéraux à la commande. Ainsi, il est toujours plus sûr de s'exécuter avec Shell = True ... J'ai donné un exemple stupide de vérification de la commande par rapport à une sorte de dictionnaire de "commande approuvée" ou de définition --- à travers elle, cela ferait plus de sens pour normaliser cela dans un chemin absolu, sauf si vous avez l'intention d'exiger que les arguments soient normalisés avant de passer la chaîne de commande à cette fonction.