如何记录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")
Run Code Online (Sandbox Code Playgroud)
您认为在这里可以做些什么?
编辑
基于Alex答案的两个子问题:
如何对存储在输出文件中的问题做出答案?例如,在线ok = raw_input(prompt)上将询问用户该问题,并且我也希望记录答案.
我读到有关Popen的信息并且没有使用,因为它将数据缓冲在内存中.这里输出量很大,我也需要关注标准输出的标准误差.你知道这是否可以用Popen和沟通方法处理?
让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!
Run Code Online (Sandbox Code Playgroud)
这应该适用于Python 2和Python 3.
要类似地指导子命令的输出,请不要使用
retvalue = subprocess.check_call(cmd, shell=True)
Run Code Online (Sandbox Code Playgroud)
让cmd我们的输出转到它的常规"标准输出",而是自己抓取并重新发出它,如下所示:
p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE)
so, se = p.communicate()
print(so)
retvalue = p.returncode
Run Code Online (Sandbox Code Playgroud)
假设您不关心标准错误(仅标准输出)并且输出量cmd相当小(因为.communicate内存中的数据缓冲区) - 如果任何一个假设与您的确切不对应,则很容易调整想.
编辑:OP现在已经澄清了对这个答案的长期评论中的规范:
使用如下功能:
def echoed_input(prompt):
response = raw_input(prompt)
sys.stdout.f.write(response)
return response
Run Code Online (Sandbox Code Playgroud)
而不仅仅是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
Run Code Online (Sandbox Code Playgroud)
即,只需重定向子命令的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
Run Code Online (Sandbox Code Playgroud)
(它获取并发出一条线在同一时间)可优选(这取决于cmd不是从它的标准期待任何输入,当然......因为,如果它是期待任何东西,它不会得到它,问题开始变得具有挑战性;-).
| 归档时间: |
|
| 查看次数: |
1894 次 |
| 最近记录: |