【问题标题】:How to log IPython history to text file?如何将 IPython 历史记录到文本文件?
【发布时间】:2013-05-27 08:38:20
【问题描述】:

在 IPython documentation 和一些 code 进行一些搜索和拖网之后,我似乎无法弄清楚是否可以将命令历史记录(而不是输出日志)存储到文本文件而不是 SQLite 数据库。 ipython --help-all 好像表示这个选项不存在。

这对于诸如.bash_history 中的常用命令的版本控制非常有用。

编辑Working solution 基于@minrk 的回答。

【问题讨论】:

    标签: python configuration ipython


    【解决方案1】:

    您可以使用 %history 魔法将您在 IPython 中的所有历史记录导出到一个文本文件,如下所示:

    %history -g -f filename
    

    获得所需内容的一种方法可能是在git hook 中进行导出。我通常将这些“同步外部资源”操作放在结帐后的 git 挂钩中。

    【讨论】:

    • Running ?%history 还展示了如何提取日志的特定部分,例如活动会话。
    • 这是最直接简洁的回答。这应该是首选答案。
    • 我只需要history -g
    【解决方案2】:

    您还可以选择要保存的行。例如

    %history 1 7-8 10 -f /tmp/bar.py
    

    这会将第 1、7 到 8 行和第 10 行保存到临时文件 bar.py。如果您需要整体,请跳过该行的一部分。

    %history -f /tmp/foo.py
    

    【讨论】:

      【解决方案3】:

      您可以通过在其中一个启动脚本中添加它来模拟 bash 的行为(例如 $(ipython locate profile)/startup/log_history.py:

      import atexit
      import os
      
      ip = get_ipython()
      LIMIT = 1000 # limit the size of the history
      
      def save_history():
          """save the IPython history to a plaintext file"""
          histfile = os.path.join(ip.profile_dir.location, "history.txt")
          print("Saving plaintext history to %s" % histfile)
          lines = []
          # get previous lines
          # this is only necessary because we truncate the history,
          # otherwise we chould just open with mode='a'
          if os.path.exists(histfile):
              with open(histfile, 'r') as f:
                  lines = f.readlines()
      
          # add any new lines from this session
          lines.extend(record[2] + '\n' for record in ip.history_manager.get_range())
      
          with open(histfile, 'w') as f:
              # limit to LIMIT entries
              f.writelines(lines[-LIMIT:])
      
      # do the save at exit
      atexit.register(save_history)
      

      请注意,这模拟了 bash/readline 历史行为,因为它会在解释器崩溃等情况下失败。

      in a gist

      更新:替代

      如果您真正想要的只是有一些可用于 readline 的手动收藏命令(完成、^R 搜索等),您可以进行版本控制,那么此启动文件将允许您自己维护该文件,这将纯粹是在 IPython 的实际命令历史之外:

      import os
      
      ip = get_ipython()
      
      favfile = "readline_favorites"
      
      def load_readline_favorites():
          """load profile_dir/readline_favorites into the readline history"""
          path = os.path.join(ip.profile_dir.location, favfile)
          if not os.path.exists(path):
              return
      
          with open(path) as f:
              for line in f:
                  ip.readline.add_history(line.rstrip('\n'))
      
      if ip.has_readline:
          load_readline_favorites()
      

      将其放到您的profile_default/startup/ 目录中,然后编辑profile_default/readline_favorites,或者您希望保留该文件的任何位置,它会在每个 IPython 会话的 readline 完成等中显示。

      【讨论】:

      • 现在我很困惑 - 文件是从“真实”历史记录中写入的,因此这些命令将始终是您实际历史记录中的最新命令。
      • 如果你真的只想要一个流行的命令文件,它总是在你的 readline 历史记录中,那么可能有比使用你的 IPython 历史记录更好的方法。我已经更新了我的答案,以包含一个从收藏夹文件填充 readline 历史记录的示例,但严格地除了真实历史记录之外。
      【解决方案4】:

      保存 Ipython 会话历史记录:

      %save [filename] [line start - line end] 
      

      例如:

      %save ~/Desktop/Ipython_session.txt 1-31
      

      这只会保存 ipython 历史的特定会话,但不会保存 ipython 命令的整个历史。

      【讨论】:

        【解决方案5】:

        使用纯文本文件来存储历史记录会导致来自不同会话的命令交错,并且会导致添加“从 session-x 运行第三个命令”或在历史记录中搜索等功能过于复杂和缓慢。于是有了 sqlite 数据库,

        不过,将脚本转储历史写入文件并同时进行统计应该很容易。您对文本文件所做的一切都应该可以使用 sqlite 来实现。

        【讨论】:

        • 它非常适合 Bash,即使每次执行命令都会读取数千行历史记录。就个人而言,我不会对几个会话前运行的命令有最微弱的想法,除非有一些我从未使用过的花哨的会话处理。但我不只是想要一个历史转储,而是用一个有用的功能替换当前的功能(这对我来说几乎没用)。
        • 您是使用将历史记录存储到文本文件,还是一直是数据库?在第一种情况下,我可以简单地劫持它作为分叉。
        • 以前是一个文本文件,但后来代码变了很多,不建议去挖。
        猜你喜欢
        • 1970-01-01
        • 2012-01-04
        • 2019-05-29
        • 1970-01-01
        • 1970-01-01
        • 2011-05-05
        • 1970-01-01
        • 1970-01-01
        • 2013-07-22
        相关资源
        最近更新 更多