如何在Python中通过管道执行命令?

时间:2013-06-20 18:55:38

标签: python pipe xargs

我使用find和wc来获取使用管道的总LOC。

find . -name "*.cpp" -print | xargs wc

  44     109     896 ./main.cpp
 ...
 288    1015    8319 ./src/util/util.cpp
 733    2180   21494 total

我需要使用python自动获取LOC,我将运行find .. | xargs命令多次,获取结果和进程以获得总LOC。

如何在Python中通过管道执行命令? 我尝试了这个,但它没有返回任何东西。

import subprocess
p = subprocess.Popen(['find', '.', '-name', "*.cc", "-print", "|", "xargs", "wc"], 
    stdout=subprocess.PIPE, 
    stderr=subprocess.PIPE)
out, err = p.communicate()
print out

ADDED

随着konishchev的提示,我可以让它发挥作用。

p1 = Popen(['find', '.', '-name', "*.cc", "-print"], stdout=PIPE)
p2 = Popen(["xargs", "wc"], stdin=p1.stdout, stdout=PIPE)
p1.stdout.close()  # Allow p1 to receive a SIGPIPE if p2 exits.
output = p2.communicate()[0]
print output

2 个答案:

答案 0 :(得分:1)

管道是一个shell函数。因此,Popen来电需要shell=True。否则,您的| wc将被传递给finderr将不知道如何处理它(并且可能会向os.walk发送一个错误... ... “不打印。”

但为什么要出局呢?只需在Python中完成所有这些工作(例如find替换import os, re for dirpath, dirnames, filenames in os.walk(rootpath): for filename in filenames: if filename.endswith(".cc"): with open(os.path.join(dirpath, filename)) as infile: text = infile.read() chars = len(text) lines = sum(1 for x in re.finditer(r"\n", text)) lines += not text.endswith("\n") # count last line if no newline words = sum(1 for x in re.finditer(r"\w+", text)) # do whatever with these... )它将更容易阅读和维护。类似的东西:

{{1}}

答案 1 :(得分:1)

您必须连接两个Popen对象,如here所述。

但我想推荐psh module,因为它更容易用于此类事情。