Je veux obtenir le stdout
dans une variable après avoir exécuté l'appel os.system
.
Prenons cette ligne comme exemple:
batcmd="dir"
result = os.system(batcmd)
result
contiendra le code d'erreur (stderr
0
sous Windows ou 1
sous un linux pour l'exemple ci-dessus).
Comment puis-je obtenir le stdout
pour la commande ci-dessus sans utiliser la redirection dans la commande exécutée?
Si tout ce dont vous avez besoin est la sortie stdout
, jetez un coup d'œil à subprocess.check_output()
(ajouté dans Python 2.7):
import subprocess
batcmd="dir"
result = subprocess.check_output(batcmd, Shell=True)
Comme vous utilisiez os.system()
, vous devez définir Shell=True
pour obtenir le même comportement. Vous voulez tenir compte du gros message d’avertissement rouge concernant le passage d’arguments non fiables à votre shell.
Si vous devez également capturer stderr
, ajoutez simplement stderr=subprocess.STDOUT
à l'appel:
result = subprocess.check_output([batcmd], stderr=subprocess.STDOUT)
pour rediriger la sortie d'erreur vers le flux de sortie par défaut.
Ces réponses n'ont pas fonctionné pour moi. Je devais utiliser ce qui suit:
import subprocess
p = subprocess.Popen(["pwd"], stdout=subprocess.PIPE)
out = p.stdout.read()
print out
Ou en tant que fonction (utiliser Shell = True était requis pour moi le Python 2.6.7 et check_output n'a été ajouté que le 2.7, ce qui le rend inutilisable ici):
def system_call(command):
p = subprocess.Popen([command], stdout=subprocess.PIPE, Shell=True)
return p.stdout.read()
Je voudrais développer la solution Windows. Utiliser IDLE avec Python 2.7.5, quand j'exécute ce code à partir du fichier Expts.py:
import subprocess
r = subprocess.check_output('cmd.exe dir',Shell=False)
print r
... dans le shell Python, j'obtiens UNIQUEMENT la sortie correspondant à "cmd.exe"; la partie "dir" est ignorée. CEPENDANT, lorsque j'ajoute un commutateur tel que/K ou/C ...
import subprocess
r = subprocess.check_output('cmd.exe /K dir',Shell=False)
print r
... puis dans le shell Python, j'ai tout ce que j'attendais, y compris la liste des répertoires. Woohoo!
Maintenant, si j’essaie d’utiliser l’une de ces choses sous DOS Python, fenêtre de commande, sans le commutateur ou avec le commutateur/K, il semble que la fenêtre se bloque car elle exécute un sous-processus cmd.exe et il attend d'autres entrées - tapez 'exit' puis appuyez sur [entrée] pour relâcher. Mais avec le commutateur/K, cela fonctionne parfaitement et vous renvoie à l'invite python. Allrightee alors.
Nous sommes allés un peu plus loin ... Je pensais que c'était cool ... Quand je le fais plutôt dans Expts.py:
import subprocess
r = subprocess.call("cmd.exe dir",Shell=False)
print r
... une nouvelle fenêtre DOS s'ouvre et reste affichée, affichant uniquement les résultats de "cmd.exe" et non de "dir". Lorsque j'ajoute le commutateur/C, la fenêtre DOS s'ouvre et se ferme très rapidement avant que je puisse voir quoi que ce soit (comme prévu, car/C se termine lorsque vous avez terminé). Lorsque j'ajoute le commutateur/K à la place, la fenêtre DOS s'ouvre et reste ouverte, ET j'obtiens tous les résultats attendus, y compris la liste des répertoires.
Si j'essaie la même chose (sous-processus.call au lieu de sous-processus.check_output) à partir d'une fenêtre de commande DOS Python; toutes les sorties sont dans la même fenêtre, il n'y a pas de fenêtres popup. Sans le commutateur, la partie "dir" est à nouveau ignorée ET l'invite passe de l'invite python à l'invite DOS (puisqu'un sous-processus cmd.exe est exécuté en python; tapez à nouveau "exit" et vous-même. reviendra à l'invite python). L'ajout du commutateur/K imprime la liste des répertoires et modifie l'invite de python en DOS car/K ne met pas fin au sous-processus. Le fait de basculer le commutateur sur/C nous donne toutes les sorties attendues ET retourne à l'invite python puisque le sous-processus se termine conformément à/C.
Désolé pour la réponse interminable, mais je suis frustré sur ce forum par les nombreuses "réponses" laconiques qui au mieux ne fonctionnent pas (semble parce qu'elles ne sont pas testées - comme la réponse d'Eduard F au-dessus de la mienne qui manque l'interrupteur) ou Pire, ils sont tellement laconiques qu’ils n’aident pas grand-chose du tout (par exemple, "essayez un sous-processus au lieu de os.system"… ouais, OK, maintenant quoi ??). En revanche, j'ai fourni des solutions que j'ai testées et montré à quel point il existe des différences subtiles entre elles. Cela a pris beaucoup de temps mais ... J'espère que ça aide.
commands
fonctionne également.
import commands
batcmd = "dir"
result = commands.getoutput(batcmd)
print result
Cela fonctionne sur linux, python 2.7.
Je devais utiliser os.system, car le sous-processus me renvoyait une erreur de mémoire pour les tâches plus importantes. Référence pour ce problème ici . Donc, pour obtenir le résultat de la commande os.system, j'ai utilisé cette solution de contournement:
import os
batcmd = 'dir'
result_code = os.system(batcmd + ' > output.txt')
if os.path.exists('output.txt'):
fp = open('output.txt', "r")
output = fp.read()
fp.close()
os.remove('output.txt')
print(output)