Pregunta

¿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? Intenté os.system (" cat / tmp / baz ") pero eso pone el resultado al estándar y me devuelve el código de error de esa operación.

¿Fue útil?

Solución

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

Otros consejos

La forma más flexible es utilizar el subproceso 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 anteriores la función especial check_output () se puede usar 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. Puede, por ejemplo, usar shell = True para ejecutar el programa a través del shell, si necesita cosas como expansiones de nombre de archivo de * , pero eso viene con limitaciones .

algo es correcto . También puede usar os.popen (), pero donde esté disponible el subproceso (Python 2.4+) generalmente es preferible.

Sin embargo, a diferencia de algunos idiomas que lo alientan, generalmente se considera una mala forma generar un subproceso donde puede hacer el mismo trabajo dentro del idioma. Es más lento, menos confiable y depende de la plataforma. Su 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 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í, podría incluirlo en una sola línea:

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

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 .

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

import commands

commands.getoutput("whoami")

Salida:

  

'bganesan'

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

Estoy usando

  

(6: 0) $ python - versión   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 pudo acceder al directorio / tmp. Después de mirar la cadena de documentos para el subproceso, reemplacé

  

[" prog " ;, " arg "]

con

  

" prog arg "

y obtuve el comportamiento de expansión de shell que se deseaba (a la Perl `prog arg`)

  

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 encontrar que Python ha hecho esto razonable.

Si usa subprocess.Popen, recuerde especificar bufsize. El valor predeterminado es 0, lo que significa '' sin búfer '', no '' elija un valor predeterminado razonable ''.

Esto no funcionará en python3, pero en python2 puede extender str con un método personalizado __repr__ 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`

El operador backtick (`) se eliminó en Python 3 . Es confusamente similar a una comilla simple y difícil de escribir en algunos teclados. En lugar del backtick , use la función incorporada equivalente repr () .

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top