Guardar o resultado do subprocesso.O Popen chama num texto
estou a tentar fazer uma chamada de sistema em Python e armazenar a saída para um texto que posso manipular no programa Python.
#!/usr/bin/python
import subprocess
p2 = subprocess.Popen("ntpq -p")
Tentei algumas coisas, incluindo algumas das sugestões aqui:
Mas sem sorte.
9 answers
Em Python 2.7 ou Python 3
Em vez de fazer um objecto Popen
directamente, pode usar o subprocess.check_output()
função para guardar o resultado de um comando num texto:
from subprocess import check_output
out = check_output(["ntpq", "-p"])
Em Python 2.4-2.6
Usa o método communicate
.
import subprocess
p = subprocess.Popen(["ntpq", "-p"], stdout=subprocess.PIPE)
out, err = p.communicate()
out
é o que tu queres.
Nota importante sobre as outras respostas
Repara como passei no comando. O exemplo de"ntpq -p"
traz à tona outra questão. Uma vez que Popen
não invoque a linha de comandos, você irá usar uma lista com o comando e as opções-["ntpq", "-p"]
.
Isto funcionou para mim para redireccionar o stdout (o stderr pode ser tratado da mesma forma):
from subprocess import Popen, PIPE
pipe = Popen(path, stdout=PIPE)
text = pipe.communicate()[0]
Se não funcionar para si, por favor especifique exactamente o problema que está a ter.
Assumindo que pwd
é apenas um exemplo, é assim que o podes fazer:
import subprocess
p = subprocess.Popen("pwd", stdout=subprocess.PIPE)
result = p.communicate()[0]
print result
Ver a documentação do subprocesso para outro exemplo e mais informação.
Subprocesso.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]
No construtor de Popen, se shell for True, você deve passar o comando como uma cadeia em vez de como uma sequência. Caso contrário, basta dividir o comando em uma lista:
command = ["ntpq", "-p"] # the shell command
process = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=None)
Se necessitar de ler também o erro-padrão, na inicialização do Popen, poderá configurar o stderr para subprocessamento.PIPE ou para subprocesso.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()
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
Para o Python 2.7+ A resposta idiomática é usar subprocess.check_output()
Você também deve notar o tratamento dos argumentos ao invocar um subprocesso, pois pode ser um pouco confuso....
Se args é apenas um comando sem args próprio( ou você tem shell=True
Conjunto), pode ser uma cadeia de caracteres. Caso contrário, deve ser uma lista.
Por exemplo... para invocar o comando ls
, Tudo bem:
from subprocess import check_call
check_call('ls')
Isto também é:
from subprocess import check_call
check_call(['ls',])
No entanto, se se quiser passar alguns args para o comando shell, você não pode fazer isso:
from subprocess import check_call
check_call('ls -al')
Em vez disso, você deve passá-lo como uma lista:
from subprocess import check_call
check_call(['ls', '-al'])
A shlex.split()
a função às vezes pode ser útil para dividir uma string em sintaxe shell-like antes de criar um subprocesso...
assim:
from subprocess import check_call
import shlex
check_call(shlex.split('ls -al'))
from subprocess import Popen, PIPE
def console(cmd):
p = Popen(cmd, shell=True, stdout=PIPE)
out, err = p.communicate()
return (p.returncode, out, err)
Por Exemplo:
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()
Neste caso, só terá um elemento na lista.
Eu escrevi uma pequena função baseada nas outras respostas aqui:
def pexec(*args):
return subprocess.Popen(args, stdout=subprocess.PIPE).communicate()[0].rstrip()
Utilização:
changeset = pexec('hg','id','--id')
branch = pexec('hg','id','--branch')
revnum = pexec('hg','id','--num')
print('%s : %s (%s)' % (revnum, changeset, branch))