Вопрос

Я хотел бы повторить это в Python:

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

(hg cat file.txt выводит последнюю зафиксированную версию файла file.txt)

Я знаю, как передать файл в gvimdiff, но он не принимает другой файл:

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

Переходим к части Python...

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

Когда вызывается подпроцесс, он просто проходит <(hg cat file) на gvimdiff как имя файла.

Итак, есть ли способ перенаправить команду, как это делает bash?Для простоты просто загрузите файл и перенаправьте его на diff:

diff <(cat file.txt) file.txt
Это было полезно?

Решение

Это может быть сделано.Однако, начиная с Python 2.5, этот механизм специфичен для Linux и не переносим:

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

Тем не менее, в конкретном случае diff вы можете просто взять один из файлов со стандартного ввода и исключить необходимость использования рассматриваемой функции, похожей на bash:

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]

Другие советы

Также имеется командный модуль:

import commands

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

Существует также набор функций popen, если вы хотите получить данные из команды во время ее выполнения.

На самом деле это пример в документы:

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

что для вас означает:

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]

Это устраняет использование специфичных для Linux битов /proc/self/fd, благодаря чему он, вероятно, будет работать на других системах, таких как Solaris и BSD (включая MacOS), и, возможно, даже работать на Windows.

До меня только что дошло, что вы, вероятно, ищете одну из функций popen.

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

Popen3 (cmd [, bufsize [, mode]]) выполняет CMD в качестве подпроцесса.Возвращает файловые объекты (child_stdout, child_stdin, child_stderr).

Намасте, Марк

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top