Equivalente a festança Backticks em Python
Pergunta
O que é o equivalente dos backticks encontrados em Ruby e Perl em Python? Isto é, em Ruby Eu posso fazer isso:
foo = `cat /tmp/baz`
O que faz o olhar declaração equivalente como em Python? Eu tentei os.system("cat /tmp/baz")
mas que coloca o resultado para fora padrão e retorna para me o código de erro de operação.
Solução
output = os.popen('cat /tmp/baz').read()
Outras dicas
A maneira mais flexível é usar a subprocess
módulo:
import subprocess
out = subprocess.run(["cat", "/tmp/baz"], capture_output=True)
print("program output:", out)
capture_output
foi introduzido em Python 3.7, para versões mais antigas do check_output()
função especial pode ser usado em vez disso:
out = subprocess.check_output(["cat", "/tmp/baz"])
Você também pode construir manualmente um objeto subprocess Se você precisar de multar controle de grão:
proc = subprocess.Popen(["cat", "/tmp/baz"], stdout=subprocess.PIPE)
(out, err) = proc.communicate()
Todas estas funções apoiar chave parâmetros para personalizar como exatamente o subprocesso é executado. Você pode, por exemplo, o uso shell=True
para executar o programa através do escudo, se você precisar de coisas como expansões de nome de arquivo de *
, mas que vem com limitações .
sth é direita. Você também pode usar os.popen (), mas quando disponível (Python 2.4 +) subprocesso é geralmente preferível.
No entanto, ao contrário de algumas línguas que incentivam isso, é geralmente considerado má forma para gerar um subprocesso onde você pode fazer o mesmo trabalho dentro da linguagem. É mais lento, menos confiável e dependente de plataforma. Seu exemplo seria melhor como:
foo= open('/tmp/baz').read()
eta:
baz é um diretório e eu estou tentando obter o conteúdo de todos os arquivos no diretório
? gato em um diretório me recebe um erro.
Se você quiser uma lista de arquivos:
import os
foo= os.listdir('/tmp/baz')
Se você deseja que o conteúdo de todos os arquivos em um diretório, algo como:
contents= []
for leaf in os.listdir('/tmp/baz'):
path= os.path.join('/tmp/baz', leaf)
if os.path.isfile(path):
contents.append(open(path, 'rb').read())
foo= ''.join(contents)
ou, se você pode ter certeza que não há diretórios lá dentro, você poderia se encaixar em uma frase:
path= '/tmp/baz'
foo= ''.join(open(os.path.join(path, child), 'rb').read() for child in os.listdir(path))
foo = subprocess.check_output(["cat", "/tmp/baz"])
A partir do Python 3.5 em diante, a maneira recomendada é usar subprocess.run
. Para obter o mesmo comportamento que você descreve, você usaria:
output = subprocess.run("ls", shell=True, stdout=subprocess.PIPE).stdout
Isso irá retornar um objeto bytes
. Você pode querer anexar .decode("ascii")
ou .decode("utf-8")
até o fim de obter uma str
.
A maneira mais fácil é usar o pacote de comandos.
import commands
commands.getoutput("whoami")
Output:
'bganesan'
import os
foo = os.popen('cat /tmp/baz', 'r').read()
Eu estou usando
(6: 0) $ python --version Python 2.7.1
Um dos exemplos acima é:
import subprocess
proc = subprocess.Popen(["cat", "/tmp/baz"], stdout=subprocess.PIPE, shell=True)
(out, err) = proc.communicate()
print "program output:", out
Para mim, isso não conseguiu acessar o diretório / tmp. Depois de olhar para a string doc para subprocess I substituído
[ "prog", "arg"]
com
"prog arg"
e tem o comportamento de expansão shell que foi desejado (a la de Perl `prog arg`)
imprimir subprocess.Popen ( "ls -ld / tmp / v *", stdout = subprocess.PIPE, shell = True) .communicate () [0]
eu sair usando python um tempo atrás porque eu estava irritado com a dificuldade de de fazer o equivalente a perl `cmd ...`. Eu estou contente de encontrar Python fez este razoável.
Se você usar subprocess.Popen, lembre-se de especificar bufsize. O padrão é 0, que significa "sem buffer", não "escolher um padrão razoável".
Isso não trabalho em python3, mas em python2 você pode estender str
com um método __repr__
personalizado que chama o seu comando shell e retorna-lo assim:
#!/usr/bin/env python
import os
class Command(str):
"""Call system commands"""
def __repr__(cmd):
return os.popen(cmd).read()
O que você pode usar como
#!/usr/bin/env python
from command import Command
who_i_am = `Command('whoami')`
# Or predeclare your shell command strings
whoami = Command('whoami')
who_i_am = `whoami`