【问题标题】:How to execute commands through pipe in Python?如何在 Python 中通过管道执行命令?
【发布时间】:2013-06-17 18:41:31
【问题描述】:

我使用 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

添加

有了 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

【问题讨论】:

    标签: python pipe xargs


    【解决方案1】:

    你必须像here 描述的那样连接两个 Popen 对象。

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

    【讨论】:

      【解决方案2】:

      管道是一个外壳函数。因此你的Popen 电话需要shell=True 就可以了。否则你的| wc 将被传递给find,它不知道如何处理它(并且可能会向err 发送一个错误,你没有打印)。

      但是为什么要掏空呢?只需在 Python 中完成所有这些工作(例如,os.walk 替换 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...
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-05-05
        • 2011-08-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-08-30
        • 1970-01-01
        • 2015-09-13
        相关资源
        最近更新 更多