¿Cuál es el equivalente de las comillas invertidas que se encuentran en Ruby y Perl en Python? Es decir, en Ruby puedo hacer esto:
foo = `cat /tmp/baz`
¿Cómo se ve la declaración equivalente en Python? Lo intenté, os.system("cat /tmp/baz")
pero eso pone el resultado en estándar y me devuelve el código de error de esa operación.
Respuestas:
output = os.popen('cat /tmp/baz').read()
fuente
`...`
(capturando stdout, pasando stderr a través) - con una excepción: Ruby permite determinar el código de salida del proceso vía$?
después del hecho; en Python, por lo que puedo decir, tendrás que usar lassubprocess
funciones del módulo para eso.La forma más flexible es utilizar el
subprocess
módulo:import subprocess out = subprocess.run(["cat", "/tmp/baz"], capture_output=True) print("program output:", out)
capture_output
se introdujo en Python 3.7, para versiones anteriorescheck_output()
se puede usar la función especial en su lugar:out = subprocess.check_output(["cat", "/tmp/baz"])
También puede construir manualmente un objeto de subproceso si necesita un control detallado:
proc = subprocess.Popen(["cat", "/tmp/baz"], stdout=subprocess.PIPE) (out, err) = proc.communicate()
Todas estas funciones admiten parámetros de palabras clave para personalizar cómo se ejecuta exactamente el subproceso. Por ejemplo, puede usar
shell=True
para ejecutar el programa a través del shell, si necesita cosas como expansiones de nombres de archivos*
, pero eso tiene limitaciones .fuente
subprocess.run()
(no sé si se merece) si no necesita admitir versiones anteriores o si no necesita la flexibilidad proporcionada porPopen()
.algo tiene razón . También puede usar os.popen (), pero cuando esté disponible (Python 2.4+), generalmente es preferible el subproceso.
Sin embargo, a diferencia de algunos lenguajes que lo fomentan, generalmente se considera de mala forma generar un subproceso en el que se puede hacer el mismo trabajo dentro del lenguaje. Es más lento, menos confiable y depende de la plataforma. Su ejemplo estaría mejor si:
foo= open('/tmp/baz').read()
eta:
? cat en un directorio me da un error.
Si desea una lista de archivos:
import os foo= os.listdir('/tmp/baz')
Si desea el contenido de todos los archivos en un directorio, 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)
o, si puede estar seguro de que no hay directorios allí, puede colocarlo en una sola línea:
path= '/tmp/baz' foo= ''.join(open(os.path.join(path, child), 'rb').read() for child in os.listdir(path))
fuente
foo = subprocess.check_output(["cat", "/tmp/baz"])
fuente
Desde Python 3.5 en adelante, la forma recomendada es usar
subprocess.run
. Desde Python 3.7, para obtener el mismo comportamiento que describe, usaría:cpe = subprocess.run("ls", shell=True, capture_output=True)
Esto devolverá un
subprocess.CompletedProcess
objeto. La salida a stdout estará adentrocpe.stdout
, la salida a stderr estará adentrocpe.stderr
, que serán ambosbytes
objetos. Puede decodificar la salida para obtener unstr
objeto utilizandocpe.stdout.decode()
u obtener un pasandotext=True
asubprocess.run
:cpe = subprocess.run("ls", shell=True, capture_output=True, text=True)
En el último caso,
cpe.stdout
ycpe.stderr
son ambosstr
objetos.fuente
text=True
parámetro para recuperar una cadena en lugar de bytes.La forma más sencilla es utilizar el paquete de comandos.
import commands commands.getoutput("whoami")
Salida:
fuente
import os foo = os.popen('cat /tmp/baz', 'r').read()
fuente
Estoy usando
Uno de los ejemplos anteriores es:
import subprocess proc = subprocess.Popen(["cat", "/tmp/baz"], stdout=subprocess.PIPE, shell=True) (out, err) = proc.communicate() print "program output:", out
Para mí, esto no pudo acceder al directorio / tmp. Después de mirar la cadena doc para el subproceso, reemplacé
con
y obtuvo el comportamiento de expansión de shell que se deseaba (a la Perl's `prog arg`)
Dejé de usar Python hace un tiempo porque me molestaba la dificultad de hacer el equivalente de perl `cmd ...`. Me alegra descubrir que Python ha hecho esto razonable.
fuente
Si usa subprocess.Popen, recuerde especificar bufsize. El valor predeterminado es 0, que significa "sin búfer", no "elija un valor predeterminado razonable".
fuente
Esto no funcionará en python3, pero en python2 puede extender
str
con un__repr__
método personalizado que llama a su comando de shell y lo devuelve así:#!/usr/bin/env python import os class Command(str): """Call system commands""" def __repr__(cmd): return os.popen(cmd).read()
Que puedes 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`
fuente
repr()
El
backtick
operador (`) se eliminó enPython 3
. Es confusamente similar a una comilla simple y difícil de escribir en algunos teclados. En lugar debacktick
, utilice la función incorporada equivalenterepr()
.fuente