Python脚本中有下面一行代码,它在原始脚本中运行单独的Python脚本:
subprocess.Popen("'/MyExternalPythonScript.py' " + theArgumentToPassToPythonScript, shell=True).communicate()
使用上面的行,在单独的Python文件中找到的任何print()
语句都会出现在主Python脚本的控制台中。
但是,这些语句是,而不是脚本写入的.txt文件日志中所反映的。
有谁知道如何修复这个问题,以便.txt文件准确地反映主Python脚本的真正控制台文本?
这是我用来将控制台实时保存为一个方法文件的.txt:
import sys
class Logger(object):
def __init__(self):
self.terminal = sys.stdout
self.log = open("/ScriptLog.txt", "w", 0)
def write(self, message):
self.terminal.write(message)
self.log.write(message)
sys.stdout = Logger()
我不一定喜欢这种方法。我对任何一种方法都感兴趣,这将实现我所详述的目标。
发布于 2017-12-27 16:45:16
请记住,subprocess
生成了一个新的进程,并不真正与父进程进行通信(它们几乎是独立的实体)。尽管有其名称,communicate
方法只是从父进程向子进程发送/接收数据的一种方式(例如,模拟用户在终端上输入某些内容)。
为了知道在哪里写入输出,子进程使用数字(文件标识符或文件号)。当子进程生成一个进程时,子进程只知道标准输出是O.S.中标识为7
的文件(可以说是一个数字),但差不多就是这样。子进程将独立地查询操作系统,比如“嘿!7号文件是什么?给我,我有东西要写。”(在这里了解C fork
所做的非常有用)
基本上,生成的子进程不理解您的Logger
类。它只是知道它必须将它的内容写到一个文件中:一个在O.S中唯一标识的文件,它有一个数字,并且除非另有规定,这个数字对应于标准输出的文件描述符(但正如下面第2例所解释的,如果您愿意,可以更改它)。
所以你有几个“解决方案”..。
sys.stdout
):只需让命令运行并将其输出存储到变量中,然后稍后(在父进程中)获取它:
导入os导入子进程p= subprocess.Popen("python ./run_omething.py“,shell=True,stdout=subprocess.PIPE) p.wait() p.wait() contents = p.stdout.read() #--不管Subprocess的输出现在存储在'contents‘中,让我们把它写到文件中: file_log = os.path.join(tempfile.gettempdir(),'foo.txt'),打开(file_log,'w')作为f: f.write(内容)
这样,您还可以在代码中的某个位置执行一个print(contents)
,以便向终端输出任何子进程“说”的内容。例如,脚本“./run_omething.py”就是这样的:
print("Foo1")
print("Foo2")
print("Foo3")
发布于 2017-12-27 15:58:57
你真的需要subprocess.Popen
的communicate()
方法吗?看起来你只是想要输出。这就是subprocess.check_output()
的目的。
如果您使用它,您可以使用内置的日志记录模块"tee"-ing输出流到多个目的地。
import logging
import subprocess
import sys
EXTERNAL_SCRIPT_PATH = '/path/to/talker.py'
LOG_FILE_PATH = '/path/to/debug.log'
logger = logging.getLogger('')
logger.setLevel(logging.INFO)
# Log to screen
console_logger = logging.StreamHandler(sys.stdout)
logger.addHandler(console_logger)
# Log to file
file_logger = logging.FileHandler(LOG_FILE_PATH)
logger.addHandler(file_logger)
# Driver script output
logger.info('Calling external script')
# External script output
logger.info(
subprocess.check_output(EXTERNAL_SCRIPT_PATH, shell=True)
)
# More driver script output
logger.info('Finished calling external script')
和往常一样,小心使用shell=True
。如果您可以将调用写为subprocess.check_output(['/path/to/script.py', 'arg1', 'arg2'])
,请这样做!
https://stackoverflow.com/questions/47999670
复制相似问题