在Python中将命令重定向到另一个输入

时间:2020-03-05 18:57:31  来源:igfitidea点击:

我想在python中复制它:

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

(汞猫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

解决方案

回答

还有命令模块:

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 [,mode]])
将cmd作为子进程执行。返回文件对象(child_stdout,child_stdin,child_stderr)。

namaste,
标记

回答

可以办到。但是,从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]

回答

这实际上是文档中的一个示例:

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)之类的其他unices上运行,甚至可能在Windows上运行。