Перенаправить команду на ввод другой в 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 есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
7
0
4 828
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

Также есть модуль команд:

import commands

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

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

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

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

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

намасте отметка

Я не отрицал ваш ответ, но имейте в виду, что модуль подпроцесса предназначен для замены модулей popen *.

tzot 25.04.2009 02:23
Ответ принят как подходящий

Это может быть сделано. Однако, начиная с 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 вы можете просто взять один из файлов из stdin и избавиться от необходимости использовать рассматриваемую функциональность 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]

Хорошее решение. Также интересно то, что делает bash:> python -c "import sys; print (sys.argv)" <(echo hello) function_proj.cc ['-c', '/ dev / fd / 63', 'function_proj.cc ']

gatoatigrado 09.04.2009 08:09

@gatoatigrado - по крайней мере, в моих системах /dev/fd является символической ссылкой на /proc/self/fd

Charles Duffy 06.06.2010 22:27

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

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.

Это отвечает на вопрос, который должен был задать автор, а не на тот, который он задал, но, тем не менее, это хороший ответ, так что я его возьму; надеюсь, ты не против. :) (кстати, в документации gvimdiff не указано, что он может читать со стандартного ввода; вы пробовали это?)

Charles Duffy 17.09.2008 07:06

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