交互式Python脚本输出存储在某个文件中

交互式Python脚本输出存储在某个文件中,python,logging,Python,Logging,如何对Python脚本完成的所有活动以及从中调用的所有脚本执行日志记录 我有几个Bash脚本,但现在编写了一个Python脚本来调用所有这些Bash脚本。我希望将这些脚本生成的所有输出存储在某个文件中 该脚本是交互式Python脚本,即包含原始输入行,因此我不能像“Python script.py | tee log.txt”那样整体使用Python脚本,因为出于某些原因,屏幕上看不到问题 下面是脚本的一个摘录,该脚本调用一个shell脚本 cmd = "somescript.sh"

如何对Python脚本完成的所有活动以及从中调用的所有脚本执行日志记录

我有几个Bash脚本,但现在编写了一个Python脚本来调用所有这些Bash脚本。我希望将这些脚本生成的所有输出存储在某个文件中

该脚本是交互式Python脚本,即包含原始输入行,因此我不能像“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\u input(prompt)
    将询问用户问题,我也希望记录答案

  • 我读过关于Popen和Communication的文章,但没有使用,因为它在内存中缓冲了数据。这里的输出量很大,我需要关心标准输出的标准误差。你们知道这是否可以用Popen来处理,也可以用通信方法来处理吗


  • Python有一个跟踪模块:。用法:
    python-m trace--trace file.py
    python有一个跟踪模块:。用法:
    python-m trace--trace file.py

    如果要捕获任何脚本的输出,那么在*nix-y系统上,可以将stdout和stderr重定向到一个文件:

    ./script.py >> /tmp/outputs.txt 2>> /tmp/outputs.txt
    

    如果您希望脚本完成所有工作,而不仅仅是它们打印的内容,那么python跟踪模块将不会跟踪python执行的外部脚本完成的工作。唯一可以跟踪程序执行的每个操作的东西是,如果您足够幸运,有一个支持它的系统。(OS X Instruments基于DTrace)

    如果您想要捕获任何脚本的输出,那么在*nix-y系统上,您可以将stdout和stderr重定向到一个文件:

    ./script.py >> /tmp/outputs.txt 2>> /tmp/outputs.txt
    

    如果您希望脚本完成所有工作,而不仅仅是它们打印的内容,那么python跟踪模块将不会跟踪python执行的外部脚本完成的工作。唯一可以跟踪程序执行的每个操作的东西是,如果您足够幸运,有一个支持它的系统。(OS X Instruments基于DTrace)

    让Python自己的
    打印同时进入终端和文件并不难:

    >>> 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!
    
    这在Python2和Python3中都应该有效

    类似地,若要引导子命令的输出,请不要使用

    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现在在对该答案的长篇评论中澄清了规格:

    • 如何在屏幕上做出答案 存储在输出文件中的问题 也例如在线ok= 原始输入(提示)用户将 如果你问我这个问题,我会的 我也喜欢这个答案
    使用以下功能:

    def echoed_input(prompt):
        response = raw_input(prompt)
        sys.stdout.f.write(response)
        return response
    
    而不仅仅是应用程序代码中的
    raw_输入
    (当然,这是专门为配合上面显示的
    tee
    class I而编写的)

    • 我读了关于波本的书,并与人交流 并且没有使用,因为它缓冲了 内存中的数据。这里是产量 它很大,我需要关心它 标准输出的标准误差 也你知道这是不是 可与Popen和 沟通方法也一样吗
    communication
    只要您的输出(和标准错误)不超过内存的容量,就可以了,比如说,根据您使用的机器类型,最多只需要几GB

    如果满足此假设,只需将上述内容重新编码为:

    p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, 
                         stderr=subprocess.STDOUT)
    so, se = p.communicate()
    print(so)
    retvalue = p.returncode
    
    i、 例如,只需重定向子命令的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
    不期望其标准输入有任何内容,当然……因为,如果期望有任何内容,它将无法获取,并且问题开始变得具有挑战性;-)

    >>> 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!
    
    这在Python2和Python3中都应该有效

    类似地,若要引导子命令的输出,请不要使用

    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现在在对该答案的长篇评论中澄清了规格:

    • 如何在屏幕上做出答案 存储在输出文件中的问题 也例如在线ok= 原始输入(提示)用户将 如果你问我这个问题,我会的 我也喜欢这个答案
    使用以下功能:

    def echoed_input(prompt):
        response = raw_input(prompt)
        sys.stdout.f.write(response)
        return response
    
    而不仅仅是应用程序代码中的
    raw_输入
    (当然,这是专门为配合上面显示的
    tee
    class I而编写的)

    • 我读了关于波本的书,并与人交流 并且没有使用,因为它缓冲了 内存中的数据。这里是产量 它很大,我需要关心它 标准误差