如何执行Python脚本以及从中调用的所有脚本执行的所有活动的日志记录?
我有几个Bash脚本,但现在编写了一个调用所有这些Bash脚本的Python脚本。我希望将这些脚本生成的所有输出存储在某个文件中。
脚本是交互式Python脚本,即包含raw_input行,所以我不能像'python script.py |那样。 tee log.txt'用于整体Python脚本,因为某些原因在屏幕上看不到问题。
以下是脚本的一段摘录,它调用了一个shell脚本。
cmd = "somescript.sh"
try:
retvalue = subprocess.check_call(cmd, shell=True)
except subprocess.CalledProcessError:
print ("script command has been failed")
sys.exit("exit from script")
您认为可以在这做什么?
修改
基于Alex答案的两个子问题:
如何对存储在输出文件中的问题做出答案?例如,在ok = raw_input(prompt)
行,系统会询问用户是否有问题,我也希望记录答案。
我读到有关Popen的信息并且没有使用,因为它将数据缓冲在内存中。这里输出量很大,我也需要关注标准输出的标准误差。你知道这是否可以用Popen和沟通方法来处理?
答案 0 :(得分:7)
让Python自己的print
转到终端和文件并不难:
>>> import sys
>>> class tee(object):
... def __init__(self, fn='/tmp/foo.txt'):
... self.o = sys.stdout
... self.f = open(fn, 'w')
... def write(self, s):
... self.o.write(s)
... self.f.write(s)
...
>>> sys.stdout = tee()
>>> print('hello world!')
hello world!
>>>
$ cat /tmp/foo.txt
hello world!
这应该适用于Python 2和Python 3。
要类似地指导子命令的输出,请不要使用
retvalue = subprocess.check_call(cmd, shell=True)
允许cmd
的输出转到常规的“标准输出”,而是自己抓取并重新发出它,如下所示:
p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE)
so, se = p.communicate()
print(so)
retvalue = p.returncode
假设您不关心标准错误(仅标准输出)并且cmd
的输出量相当小(因为.communicate
将数据缓存在内存中) - 这很容易如果任何一个假设不符合您的确切要求,就进行调整。
编辑:OP现在已经澄清了对此答案的长篇评论中的规范:
使用如下功能:
def echoed_input(prompt):
response = raw_input(prompt)
sys.stdout.f.write(response)
return response
而不仅仅是应用程序代码中的raw_input
(当然,这是专门为与上面显示的tee
类合作而编写的。)
communicate
只要您不获得更多输出(和标准错误)而不是舒适地适合内存,可以说是好的,比如根据类型的数量,最多几千兆字节你正在使用的机器。
如果符合此假设,只需将上述内容重新编码为:
p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE,
stderr=subprocess.STDOUT)
so, se = p.communicate()
print(so)
retvalue = p.returncode
即,只是重定向子命令的stderr以混入其stdout。
如果您不得不担心来自您的千兆字节(或其他),那么
p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE,
stderr=subprocess.STDOUT)
for line in p.stdout:
sys.stdout.write(p)
p.wait()
retvalue = p.returncode
(一次获取并发出一行)可能更可取(这取决于cmd
不期望其标准输入的任何内容,当然......因为,如果它 期待什么,它不会得到它,问题开始变得具有挑战性; - )。
答案 1 :(得分:1)
Python有一个跟踪模块:trace。用法:python -m trace --trace file.py
答案 2 :(得分:1)
如果要捕获任何脚本的输出,那么在* nix-y系统上,您可以将stdout和stderr重定向到文件:
./script.py >> /tmp/outputs.txt 2>> /tmp/outputs.txt
如果你希望脚本完成所有,而不仅仅是它们打印的内容,那么python跟踪模块将不会跟踪你的python执行的外部脚本所做的事情。如果你足够幸运拥有一个支持它的系统,唯一可以跟踪程序完成每个操作的东西就像DTrace。 (OS X Instruments基于DTrace)