gpt4 book ai didi

使用子进程的python脚本,将所有输出重定向到文件

转载 作者:太空宇宙 更新时间:2023-11-03 15:06:35 25 4
gpt4 key购买 nike

我正在为不同语言的源代码静态分析编写一些东西。由于任何东西都必须是开源的并且可以从命令行调用,所以我现在已经为每种语言下载了一个工具。所以我决定编写一个 python 脚本,列出项目文件夹中的所有源文件并调用相应的工具。

所以我的部分代码如下所示:

import os
import sys
import subprocess
from subprocess import call
from pylint.lint import Run as pylint


class Analyser:

def __init__(self, source=os.getcwd(), logfilename=None):

# doing initialization stuff
self.logfilename = logfilename or 'CodeAnalysisReport.log'

self.listFiles()
self.analyseFiles()


def listFiles(self):
# lists all source files in the specified directory


def analyseFiles(self):

self.analysePythons()
self.analyseCpps()
self.analyseJss()
self.analyseJavas()
self.analyseCs()


if __name__ == '__main__':

Analyser()

让我们看一下 C++ 文件部分(我使用 Cppcheck 来分析它们):

    def analyseCpps(self):

for sourcefile in self.files['.cc'] + self.files['.cpp']:
print '\n'*2, '*'*70, '\n', sourcefile
call(['C:\\CodeAnalysis\\cppcheck\\cppcheck', '--enable=all', sourcefile])

其中一个文件(它只是一个随机下载的文件)的控制台输出是:

**********************************************************************
C:\CodeAnalysis\testproject\cpp\BiggestUnInt.cc
Checking C:\CodeAnalysis\testproject\cpp\BiggestUnInt.cc...
[C:\CodeAnalysis\testproject\cpp\BiggestUnInt.cc:18]: (style) The scope of the variable 'oldi' can be reduced.
[C:\CodeAnalysis\testproject\cpp\BiggestUnInt.cc:43]: (style) The scope of the variable 'lastbit' can be reduced.
[C:\CodeAnalysis\testproject\cpp\BiggestUnInt.cc:44]: (style) The scope of the variable 'two_to_power_i' can be reduced.
(information) Cppcheck cannot find all the include files (use --check-config for details)

第 1 行和第 2 行来 self 的脚本,第 3 到第 7 行来自 Cppcheck。

这就是我想要保存到我的日志文件中的内容,对于所有其他文件也是如此。一切都在一个文件中。

当然搜了SO,找到了一些方法。但没有一个能完全发挥作用。

第一次尝试:

添加sys.stdout = open(self.logfilename, 'w')给我的构造函数。这使得上面显示的输出的第 1 行和第 2 行被写入我的日志文件。其余部分仍显示在控制台上。

第二次尝试:

此外,在 analyseCpps我使用:

call(['C:\CodeAnalysis\cppcheck\cppcheck', '--enable=all', sourcefile], <strong>stdout=sys.stdout</strong>)

这使我的日志文件成为:

Checking C:\CodeAnalysis\testproject\cpp\BiggestUnInt.cc...


**********************************************************************
C:\CodeAnalysis\testproject\cpp\BiggestUnInt.cc

控制台输出为:

[C:\CodeAnalysis\testproject\cpp\BiggestUnInt.cc:18]: (style) The scope of the variable 'oldi' can be reduced.
[C:\CodeAnalysis\testproject\cpp\BiggestUnInt.cc:43]: (style) The scope of the variable 'lastbit' can be reduced.
[C:\CodeAnalysis\testproject\cpp\BiggestUnInt.cc:44]: (style) The scope of the variable 'two_to_power_i' can be reduced.

不是我想要的。

第三次尝试:

使用 Popenpipe . sys.stdout恢复为默认值。

作为前期工作analyseCpps现在是:

for sourcefile in self.files['.cc'] + self.files['.cpp']:

print '\n'*2, '*'*70, '\n', sourcefile
p = subprocess.Popen(['C:\\CodeAnalysis\\cppcheck\\cppcheck', '--enable=all', sourcefile], stdout=subprocess.PIPE)
p.stdout.read()

p.stdout.read()只显示我想要的输出的最后一行(代码框 3 中的第 7 行)

第四次尝试:

使用 subprocess.Popen(['C:\CodeAnalysis\cppcheck\cppcheck', '--enable=all', sourcefile], <strong>stdout=open(self.logfilename, 'a+')</strong>)只写一行 Checking C:\CodeAnalysis\testproject\cpp\BiggestUnInt.cc...到我的日志文件,其余部分显示在控制台上。

第五次尝试:

而不是 subprocess.Popen我用 os.system ,所以我的调用命令是:

os.system('C:\CodeAnalysis\cppcheck\cppcheck --enable=all %s >> %s' % (sourcefile, self.logfilename))

这会生成与我第四次尝试相同的日志文件。如果我直接在 Windows 控制台中键入相同的命令,结果是相同的。所以我想这不完全是 python 问题,但仍然是:

如果它在控制台上,则必须有办法将其放入文件中。有什么想法吗?


E D I T

我傻了。我还是菜鸟,所以我忘记了 stderr .这就是决定性信息的去向。

所以现在我有:

def analyseCpps(self):

for sourcefile in self.files['.cc'] + self.files['.cpp']:
p = subprocess.Popen(['C:\\CodeAnalysis\\cppcheck\\cppcheck', '--enable=all', sourcefile], stderr=subprocess.PIPE)
with open(self.logfilename, 'a+') as logfile:
logfile.write('%s\n%s\n' % ('*'*70, sourcefile))
for line in p.stderr.readlines():
logfile.write('%s\n' % line.strip())

而且它工作正常。


另一个编辑

根据 Didier 的回答:

sys.stdout = open(self.logfilename, 'w', 0)在我的构造函数中:

def analyseCpps(self):

for sourcefile in self.files['.cc'] + self.files['.cpp']:
print '\n'*2, '*'*70, '\n', sourcefile
p = subprocess.Popen(['C:\\CodeAnalysis\\cppcheck\\cppcheck', '--enable=all', sourcefile], stdout=sys.stdout, stderr=sys.stdout)

最佳答案

有几个问题:

  • 你应该同时重定向 stdout 和 stderr
  • 如果您想混合正常打印和启动命令的输出,您应该使用无缓冲文件。

像这样:

import sys, subprocess

# Note the 0 here (unbuffered file)
sys.stdout = open("mylog","w",0)

print "Hello"
print "-----"

subprocess.call(["./prog"],stdout=sys.stdout, stderr=sys.stdout)
print "-----"
subprocess.call(["./prog"],stdout=sys.stdout, stderr=sys.stdout)
print "-----"

print "End"

关于使用子进程的python脚本,将所有输出重定向到文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31963956/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com