Перенаправить команду на ввод другой в Python
Вопрос
Я хотел бы повторить это в 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).
Намасте, Марк