Frage

Das möchte ich in Python replizieren:

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

(hg cat file.txt gibt die zuletzt verpflichten Version von datei.txt)

Ich weiß, wie Rohr der Datei zu gvimdiff, aber es wird eine andere Datei nicht akzeptieren:

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

Der Weg zum Python-Teil ...

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

Wenn subprocess es nur genannt wird, geht <(hg cat file) auf gvimdiff als Dateinamen.

So ist es eine Möglichkeit, einen Befehl zu umleiten wie bash tut? Der Einfachheit nur Katze zuliebe eine Datei und leiten es zu diff:

diff <(cat file.txt) file.txt
War es hilfreich?

Lösung

Es kann getan werden. Ab Python 2.5, jedoch ist dieser Mechanismus Linux-spezifisch und nicht tragbar:

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

Wie gesagt, im speziellen Fall von diff, können Sie einfach nehmen Sie eine der Dateien aus stdin, und entfernen Sie die Notwendigkeit, die bash-alike-Funktionalität in Frage zu verwenden:

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]

Andere Tipps

Es gibt auch die Befehle Modul:

import commands

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

Es gibt auch die popen Reihe von Funktionen, wenn Sie wollen tatsächlich die Daten von einem Befehl grok wie er ausgeführt wird.

Dies ist tatsächlich ein Beispiel in der docs :

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

Das bedeutet für Sie:

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]

Dies entfernt die Verwendung des Linux-spezifisch / proc / self / fd Bits, ist es wahrscheinlich auf anderen Unix-Varianten wie Solaris und den BSDs macht Arbeit (einschließlich MacOS) und vielleicht sogar unter Windows arbeiten.

Es mir nur dämmerte, dass Sie wahrscheinlich für eine der popen Funktionen suchen.

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

popen3 (cmd [, BUFSIZE [, Modus]])     Führt cmd als Teilprozess. Gibt die Dateiobjekte (child_stdout, child_stdin, child_stderr).

namaste, Mark

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top