Pergunta

Eu gostaria de replicar isso em python:

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

(hg cat file.txt gera a versão confirmada mais recentemente de file.txt)

Eu sei como canalizar o arquivo para o gvimdiff, mas ele não aceita outro arquivo:

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

Chegando à parte do python...

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

Quando o subprocesso é chamado, ele simplesmente passa <(hg cat file) para gvimdiff como um nome de arquivo.

Então, existe alguma maneira de redirecionar um comando como o bash faz?Para simplificar, apenas cat um arquivo e redirecione-o para diff:

diff <(cat file.txt) file.txt
Foi útil?

Solução

Pode ser feito.A partir do Python 2.5, entretanto, este mecanismo é específico do Linux e não é 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()

Dito isto, no caso específico do diff, você pode simplesmente pegar um dos arquivos do stdin e eliminar a necessidade de usar a funcionalidade semelhante ao bash em questão:

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]

Outras dicas

Existe também o módulo de comandos:

import commands

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

Há também o conjunto de funções popen, se você quiser realmente entender os dados de um comando enquanto ele está em execução.

Na verdade, este é um exemplo no documentos:

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

o que significa para você:

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]

Isso remove o uso dos bits /proc/self/fd específicos do Linux, fazendo com que provavelmente funcione em outros dispositivos como Solaris e BSDs (incluindo MacOS) e talvez até funcione no Windows.

Acabei de perceber que você provavelmente está procurando uma das funções popen.

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

Popen3 (cmd [, bufsize [, modo]]) executa o CMD como um subprocesso.Retorna os objetos do arquivo (child_stdout, child_stdin, child_stderr).

Namaste, Mark

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top