Equivalente de Bash Backticks en Python
(10)
Desde Python 3.5 en adelante, la forma recomendada es usar subprocess.run
. Para obtener el mismo comportamiento que usted describe, usaría:
output = subprocess.run("ls", shell=True, stdout=subprocess.PIPE).stdout
Esto devolverá un objeto bytes
. Es posible que desee agregar .decode("ascii")
o .decode("utf-8")
al final para obtener un str
.
¿Cuál es el equivalente de los backticks encontrados 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? He intentado con 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.
Esto no funcionará en python3, pero en python2 puede ampliar str
con un método __repr__
personalizado que llame a su comando de shell y lo devuelva 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`
Estoy usando
(6: 0) $ python --version Python 2.7.1
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 ha podido acceder al directorio / tmp. Después de mirar la cadena de documentación para el subproceso que reemplacé
["prog", "arg"]
con
"prog arg"
y obtuve el comportamiento de expansión de shell que se deseaba (a la `prog arg` de Perl)
print subprocess.Popen ("ls -ld / tmp / v *", stdout = subprocess.PIPE, shell = True) .communicate () [0]
Dejé de usar Python hace un tiempo porque estaba molesto con la dificultad de hacer el equivalente de perl `cmd ...`. Me alegra descubrir que Python ha hecho esto razonable.
La forma más fácil es usar el paquete de comandos.
import commands
commands.getoutput("whoami")
Salida:
''bganesan''
La forma más flexible es usar el módulo de subprocess
:
import subprocess
proc = subprocess.Popen(["cat", "/tmp/baz"], stdout=subprocess.PIPE)
(out, err) = proc.communicate()
print "program output:", out
Si desea pasar la llamada a través del shell, por ejemplo para obtener la extensión del nombre de archivo con *
, puede usar el parámetro shell=True
. Si hace esto, debe proporcionar el comando como una cadena, citada / ... como si la ingresara en el indicador de shell:
proc = subprocess.Popen(''cat /tmp/ba* "s p a c e.txt"'', shell=True, ...)
Si usa subprocess.Popen, recuerde especificar bufsize. El valor predeterminado es 0, que significa "sin búfer", no "elegir un valor predeterminado razonable".
eso es correcto También puede usar os.popen (), pero donde esté disponible (Python 2.4+) el subproceso generalmente es preferible.
Sin embargo, a diferencia de algunos idiomas que lo fomentan, generalmente se considera una mala forma generar un subproceso en el que puede hacer el mismo trabajo dentro del idioma. Es más lento, menos confiable y depende de la plataforma. Tu ejemplo sería mejor como:
foo= open(''/tmp/baz'').read()
eta:
baz es un directorio y estoy tratando de obtener el contenido de todos los archivos en ese directorio
? cat en un directorio me da un error.
Si quieres 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í, podría caber en un solo trazo:
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"])
import os
foo = os.popen(''cat /tmp/baz'', ''r'').read()
output = os.popen(''cat /tmp/baz'').read()