Redirect command to input another in Python

I would like to reproduce this in python:

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

(hg cat file.txt displays the latest version of file.txt)

I know how to transfer a file to gvimdiff, but it will not accept another file:

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

How to get to the python part ...

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

When a subprocess is called, it simply passes <(hg cat file) to gvimdiff as the file name.

So, is there a way to redirect the command as bash? For simplicity, just write the file and redirect it to diff:

 diff <(cat file.txt) file.txt 
+6
redirect python bash diff vimdiff
source share
4 answers

It can be done. However, with Python 2.5, this mechanism is specific to Linux and is not portable:

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

However, in the specific case of diff, you can simply take one of the files from stdin and remove the need to use the bash -alike function in question:

 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] 
+9
source share

There is also a module of commands:

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

There is also a set of functions if you want to actually collect data from a command when it is running.

+2
source share

This is actually an example in docs :

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

which means for you:

 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] 

This eliminates the use of Linux-specific / proc / self / fd bits, which makes it likely to work with other systems such as Solaris and BSD (including MacOS), and possibly even work with Windows.

+2
source share

It just dawned on me that you're probably looking for one of the popen functions.

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

popen3 (cmd [, bufsize [, mode]]) Executes cmd as a subprocess. Returns file objects (child_stdout, child_stdin, child_stderr).

Namast, Mark

-one
source share

All Articles