将命令重定向到 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 那样重定向命令呢?为了简单起见,只需 cat 一个文件并将其重定向到 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 的特定情况下,您可以简单地从 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]
其他提示
还有命令模块:
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 位的使用,使其可能在其他 unice 上工作,如 Solaris 和 BSD(包括 MacOS),甚至可能在 Windows 上工作。
我突然意识到您可能正在寻找 popen 函数之一。
从: http://docs.python.org/lib/module-popen2.html
popen3(cmd [,bufsize [,mode]])将CMD执行为子过程。返回文件对象(child_stdout、child_stdin、child_stderr)。
纳马斯特,马克
不隶属于 StackOverflow