Pregunta Equivalente de Bash Backticks en Python


¿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 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.


74
2017-09-11 13:47


origen


Respuestas:


output = os.popen('cat /tmp/baz').read()

83
2017-09-11 13:53



La forma más flexible es usar el subprocess módulo:

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 expansión del nombre de archivo con *, puedes usar el shell=True parámetro. 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, ...)

78
2017-09-11 13:52



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))

25
2017-09-11 14:00



foo = subprocess.check_output(["cat", "/tmp/baz"])

14
2017-09-19 09:58



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 bytes objeto. Es posible que desee agregar .decode("ascii") o .decode("utf-8") hasta el final para obtener un str.


5
2018-03-22 16:39



La forma más fácil es usar el paquete de comandos.

import commands

commands.getoutput("whoami")

Salida:

'bganesan'


4
2017-07-28 17:48



import os
foo = os.popen('cat /tmp/baz', 'r').read()

3
2017-09-11 13:55



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.


2
2018-03-11 23:13