Pregunta

Me gustaría replicar esto en Python:

gvimdiff <(hg cat file.txt) file.txt

(hg cat file.txt genera la versión confirmada más reciente de file.txt)

Sé cómo canalizar el archivo a gvimdiff, pero no acepta otro archivo:

$ hg cat file.txt | gvimdiff file.txt -
Too many edit arguments: "-"

Llegando a la parte de Python...

# hgdiff.py
import subprocess
import sys
file = sys.argv[1]
subprocess.call(["gvimdiff", "<(hg cat %s)" % file, file])

Cuando se llama al subproceso, simplemente pasa <(hg cat file) sobre gvimdiff como nombre de archivo.

Entonces, ¿hay alguna forma de redirigir un comando como lo hace bash?En aras de la simplicidad, simplemente capture un archivo y rediríjalo a diff:

diff <(cat file.txt) file.txt
¿Fue útil?

Solución

Se puede hacer.Sin embargo, a partir de Python 2.5, este mecanismo es específico de Linux y no es portátil:

import subprocess
import sys

file = sys.argv[1]
p1 = subprocess.Popen(['hg', 'cat', file], stdout=subprocess.PIPE)
p2 = subprocess.Popen([
    'gvimdiff',
    '/proc/self/fd/%s' % p1.stdout.fileno(),
    file])
p2.wait()

Dicho esto, en el caso específico de diff, simplemente puedes tomar uno de los archivos de stdin y eliminar la necesidad de usar la funcionalidad similar a bash en cuestión:

file = sys.argv[1]
p1 = subprocess.Popen(['hg', 'cat', file], stdout=subprocess.PIPE)
p2 = subprocess.Popen(['diff', '-', file], stdin=p1.stdout)
diff_text = p2.communicate()[0]

Otros consejos

También está el módulo de comandos:

import commands

status, output = commands.getstatusoutput("gvimdiff <(hg cat file.txt) file.txt")

También existe el conjunto de funciones popen, si realmente desea asimilar los datos de un comando mientras se ejecuta.

Este es en realidad un ejemplo en el documentos:

p1 = Popen(["dmesg"], stdout=PIPE)
p2 = Popen(["grep", "hda"], stdin=p1.stdout, stdout=PIPE)
output = p2.communicate()[0]

lo que significa para ti:

import subprocess
import sys

file = sys.argv[1]
p1 = Popen(["hg", "cat", file], stdout=PIPE)
p2 = Popen(["gvimdiff", "file.txt"], stdin=p1.stdout, stdout=PIPE)
output = p2.communicate()[0]

Esto elimina el uso de los bits /proc/self/fd específicos de Linux, lo que hace que probablemente funcione en otros Unices como Solaris y BSD (incluido MacOS) y tal vez incluso funcione en Windows.

Me acabo de dar cuenta de que probablemente estés buscando una de las funciones popen.

de: http://docs.python.org/lib/module-popen2.html

Popen3 (CMD [, BufSize [, Mode]]) ejecuta CMD como un subproceso.Devuelve los objetos del archivo (child_stdout, child_stdin, child_stderr).

Namaste, Mark

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