Stockez la sortie du sous-processus.Popen appel dans une chaîne de caractères
j'essaie de faire un appel système en Python et de stocker la sortie sur une chaîne que je peux manipuler dans le programme Python.
#!/usr/bin/python
import subprocess
p2 = subprocess.Popen("ntpq -p")
j'ai essayé quelques choses, y compris certaines des suggestions ici:
extraire la sortie du sous-processus.call ()
mais sans succès.
9 réponses
en Python 2.7 ou Python 3
au lieu de faire un objet Popen
directement, Vous pouvez utiliser la subprocess.check_output()
fonction pour stocker la sortie d'une commande dans une chaîne de caractères:
from subprocess import check_output
out = check_output(["ntpq", "-p"])
En Python 2.4-2.6
utiliser la méthode communicate
.
import subprocess
p = subprocess.Popen(["ntpq", "-p"], stdout=subprocess.PIPE)
out, err = p.communicate()
out
est ce que vous voulez.
Note importante à propos des autres réponses
notez comment j'ai passé la commande. L'exemple "ntpq -p"
soulève une autre question. Puisque Popen
n'invoque pas le shell, vous utiliserez une liste de la commande et des options - ["ntpq", "-p"]
.
cela a fonctionné pour moi pour rediriger stdout (stderr peut être manipulé de manière similaire):
from subprocess import Popen, PIPE
pipe = Popen(path, stdout=PIPE)
text = pipe.communicate()[0]
si cela ne fonctionne pas pour vous, s'il vous plaît spécifier exactement le problème que vous avez.
en supposant que pwd
n'est qu'un exemple, voici comment vous pouvez le faire:
import subprocess
p = subprocess.Popen("pwd", stdout=subprocess.PIPE)
result = p.communicate()[0]
print result
voir la documentation de sous-processus pour un autre exemple et plus d'informations.
sous-processus.Popen: http://docs.python.org/2/library/subprocess.html#subprocess.Popen
import subprocess
command = "ntpq -p" # the shell command
process = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=None, shell=True)
#Launch the shell command:
output = process.communicate()
print output[0]
dans le constructeur Popen, si shell est True , vous devez passer la commande comme une chaîne plutôt que comme une séquence. Sinon, il suffit de diviser la commande en une liste:
command = ["ntpq", "-p"] # the shell command
process = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=None)
si vous avez besoin de lire aussi l'erreur standard, dans L'initialisation Popen, vous peuvent ensemble stderr à sous-processus.Tubes ou à la sous-procédure .STDOUT :
import subprocess
command = "ntpq -p" # the shell command
process = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
#Launch the shell command:
output, error = process.communicate()
cela fonctionne parfaitement pour moi:
import subprocess
try:
#prints results and merges stdout and std
result = subprocess.check_output("echo %USERNAME%", stderr=subprocess.STDOUT, shell=True)
print result
#causes error and merges stdout and stderr
result = subprocess.check_output("copy testfds", stderr=subprocess.STDOUT, shell=True)
except subprocess.CalledProcessError, ex: # error code <> 0
print "--------error------"
print ex.cmd
print ex.message
print ex.returncode
print ex.output # contains stdout and stderr together
pour Python 2.7+ la réponse idiomatique est d'utiliser subprocess.check_output()
vous devriez également noter le traitement des arguments lors de l'invocation d'un sous-processus, car il peut être un peu confus....
si args n'est qu'une seule commande sans args (ou si vous avez shell=True
), il peut s'agir d'une chaîne. Autrement, elle doit être une liste.
par exemple... pour appeler la "151970920 de la commande", ce qui est bien:
from subprocess import check_call
check_call('ls')
ainsi est-il:
from subprocess import check_call
check_call(['ls',])
cependant, si vous souhaitez passer quelques arguments pour la commande shell, vous ne peut pas faites ceci:
from subprocess import check_call
check_call('ls -al')
au lieu de cela, vous devez le passer comme une liste:
from subprocess import check_call
check_call(['ls', '-al'])
la fonction shlex.split()
peut parfois être utile pour séparer une chaîne de caractères en syntaxe shell avant la création d'un sous-processus...
comme ceci:
from subprocess import check_call
import shlex
check_call(shlex.split('ls -al'))
C'était parfait pour moi. Vous obtiendrez le code de retour, stdout et stderr dans un tuple.
from subprocess import Popen, PIPE
def console(cmd):
p = Popen(cmd, shell=True, stdout=PIPE)
out, err = p.communicate()
return (p.returncode, out, err)
Par Exemple:
result = console('ls -l')
print 'returncode: %s' % result[0]
print 'output: %s' % result[1]
print 'error: %s' % result[2]
import os
list = os.popen('pwd').read()
Dans ce cas, vous n'avez qu'un seul élément dans la liste.
j'ai écrit une petite fonction basée sur les autres réponses ici:
def pexec(*args):
return subprocess.Popen(args, stdout=subprocess.PIPE).communicate()[0].rstrip()
Utilisation:
changeset = pexec('hg','id','--id')
branch = pexec('hg','id','--branch')
revnum = pexec('hg','id','--num')
print('%s : %s (%s)' % (revnum, changeset, branch))