J'ai trouvé de la documentation sur subprocess.check_output () mais je ne trouve pas d'argument et la documentation n'est pas très détaillée. J'utilise Python 3 (mais j'essaie d'exécuter un fichier Python 2 par le biais de Python 3)
J'essaie d'exécuter cette commande: python py2.py -i test.txt
-i est un argument de position pour argparse, test.txt est ce que est le -i, py2.py est le fichier à exécuter.
J'ai essayé beaucoup de variations (non fonctionnelles), notamment: py2output = subprocess.check_output([str('python py2.py '),'-i', 'test.txt'])
py2output = subprocess.check_output([str('python'),'py2.py','-i', test.txt'])
La bonne réponse (avec Python 2.7 et ultérieur, étant donné que check_output()
a été introduit à ce moment-là )) est la suivante:
py2output = subprocess.check_output(['python','py2.py','-i', 'test.txt'])
Pour démontrer, voici mes deux programmes:
py2.py:
import sys
print sys.argv
py3.py:
import subprocess
py2output = subprocess.check_output(['python', 'py2.py', '-i', 'test.txt'])
print('py2 said:', py2output)
Le lancer:
$ python3 py3.py
py2 said: b"['py2.py', '-i', 'test.txt']\n"
Voici ce qui ne va pas avec chacune de vos versions:
py2output = subprocess.check_output([str('python py2.py '),'-i', 'test.txt'])
Tout d'abord, str('python py2.py')
est exactement la même chose que 'python py2.py'
- vous prenez un str
et appelez str
pour le convertir en un str
. Cela rend le code plus difficile à lire, plus long et même plus lent, sans aucun avantage.
Plus sérieusement, python py2.py
Ne peut être un seul argument, sauf si vous essayez réellement de lancer un programme nommé, disons, /usr/bin/python\ py2.py
. Ce que vous n'êtes pas; vous essayez de lancer, par exemple, /usr/bin/python
avec le premier argument py2.py
. Vous devez donc en faire des éléments distincts dans la liste.
Votre deuxième version corrige cela, mais il vous manque le '
Avant test.txt'
. Cela devrait vous donner un SyntaxError
, probablement en disant EOL while scanning string literal
.
En attendant, je ne sais pas comment vous avez trouvé la documentation mais vous n’avez trouvé aucun exemple avec des arguments. Le tout premier exemple est:
>>> subprocess.check_output(["echo", "Hello World!"])
b'Hello World!\n'
Cela appelle la commande "echo"
Avec un argument supplémentaire, "Hello World!"
.
Aussi:
-i est un argument de position pour argparse, test.txt est ce que signifie -i
Je suis presque certain que -i
N'est pas un argument de position, mais un argument optionnel. Sinon, la deuxième partie de la phrase n’a aucun sens.
Ajoutant à celui mentionné par @abarnert
un meilleur est d'attraper l'exception
import subprocess
try:
py2output = subprocess.check_output(['python', 'py2.py', '-i', 'test.txt'],stderr= subprocess.STDOUT)
#print('py2 said:', py2output)
print "here"
except subprocess.CalledProcessError as e:
print "Calledprocerr"
this stderr = sous-processus.STDOUT est destiné à vous assurer que vous n'obtenez pas l'erreur filenotfound dans stderr - qui ne peut généralement pas être prise dans filenotfoundexception, sinon vous finissiez par obtenir
python: can't open file 'py2.py': [Errno 2] No such file or directory
Envisager une meilleure solution à ce problème pourrait être de vérifier si le fichier/les scripts existent, puis d’exécuter le fichier/le script
Depuis Python 3.5, subprocess.run () est recommandé sur subprocess.check_output () :
>>> subprocess.run(['cat','/tmp/text.txt'], stdout=subprocess.PIPE).stdout
b'First line\nSecond line\n'
Depuis Python 3.7, au lieu de ce qui précède, vous pouvez utiliser capture_output=true
paramètre pour capturer stdout et stderr:
>>> subprocess.run(['cat','/tmp/text.txt'], capture_output=True).stdout
b'First line\nSecond line\n'
Aussi, vous voudrez peut-être utiliser universal_newlines=True
ou son équivalent depuis Python 3.7 text=True
pour travailler avec du texte au lieu de binaire:
>>> stdout = subprocess.run(['cat', '/tmp/text.txt'], capture_output=True, text=True).stdout
>>> print(stdout)
First line
Second line
Voir subprocess.run () documentation pour plus d'informations.