问题 如何避免在ipython历史记录中存储命令?


在bash中,我可以通过在其前面放置一个空格来阻止命令被保存到bash历史记录中。我不能在ipython中使用这个方法。我如何在ipython中做相同的操作?


11354
2018-01-29 20:35


起源

有关: stackoverflow.com/questions/19606275/... - ShreevatsaR


答案:


过时注意:这是写的 IPython 4.0.1从v5开始,IPython不再使用 readline


没有库存方式,可以添加或解决。

IPython中有两种历史:

  • readline 历史。它有特殊键/组合键(上/下,Ctrl-R等)。仅存储输入的行(带有 <Enter>)在控制台上(或,在 pyreadline,也从剪贴板粘贴)。 IPython依赖于本地实现 蟒蛇 readline API 它没有“不添加”功能,通常会将每一行添加到历史记录中。
    IPython有一个减轻这个的工具, IPython.core.interactiveshell.ReadlineNoRecord,创建历史快照的上下文管理器然后恢复它。作为 ipython 4.0.1,它只用于 %run 魔术避免将脚本交互输入添加到历史记录中。

  • IPython历史。它保存在DB和自动变量中。它包含完整的输入(readline 抓住每一个 <Enter>'ed line line for multipleline one)和输出。保存在。中实现 HistoryManager.store_inputs() (用于输入)和 HistoryManager.store_output() (用于输出)从中调用 InteractiveShell.run_cell 并受其管辖 store_history 论据。后者又被称为 TerminalInteractiveShell.interact 同 store_history=True

有两种方法可以解决任何一层的问题:

  • 防止首先添加输入。这不能通过前缀为命令的魔法来完成,只能使用一个作为单独命令运行并切换标志的魔法。这是因为,正如您所见,当魔术命令获得控制时,当前输入已经存储。

    • readline:公共API中没有相关条目,因此它是特定于实现的。例如。对于 pyreadline,添加完成 pyreadline.modes.basemode.BaseMode.add_history()。模式对象可以访问 get_ipython().readline.rl.mode
    • 装饰 run_cell 和 add_history 用包装器检查相应对象中的标志和a 自定义魔术命令 设置/切换它们应该可以解决问题。
  • 自动删除 证据 执行后立即输入/输出历史记录。这可以使用前缀魔术来完成。

    • IPython的: HistoryManager 没有任何设施可以删除条目(既不是DB也不是变量)。唉,用手砍掉DB /更换库存 HistoryManager 是必要的。另请注意,该类具有可选的缓存 HistoryManager.db_cache_size (默认情况下禁用)。
    • readline的: remove_history_item(index) 在API中。您需要知道输入中的行数。

或者, 如果您只需要输入密码,请考虑其他不在屏幕上回显密码的方法 (因此不会使其成为控制台历史记录的一部分):

  • getpass.getpass()
  • 将它存储在别处(就像你只能读取的配置文件一样)

4
2018-01-30 03:02



1。 “首先防止添加输入。这不能通过一个前缀为命令的魔法来完成,只能使用一个作为单独命令运行并切换标志的魔法” 什么是单独的命令切换标志以防止添加输入的示例? 2。 使用包装器检查run_cell和add_history以及相应对象中的标志和设置/切换它们的自定义魔术命令应该可以解决问题。 你能加一个例子吗? - ShreevatsaR
@ShreevatsaR 0)看到过时的注意事项; 1)%toggle,your_command,%toggle; 2)这意味着用它们周围的包装来代替这些功能;一个例子超出了答案的范围,任何拥有体面专业知识的人都应该清楚这一点。 - ivan_pozdeev


我想我终于搞清楚了。这种方法并没有真正“阻止”ipython记录历史,但实际上 删除 历史记录。但我认为这仍然是实现这一目标的好方法。

ipython历史存储在一个 sqlite数据库 档案 $(ipython locate)/profile_default/history.sqlite

数据库表 历史 有四列: 会议线资源 和 source_raw。该 会议 专栏介绍 session_id 当前会话,可以使用ipython中的方法获取: get_ipython().history_manager.hisdb.get_last_session_id() 在 ipython。该 线 列只是行号。

所以我要做的就是我要去 删除 这条记录在数据库中 ipython 环境:

1)历史数据库对象可以使用 get_ipython().history_manager.db 在 ipython

hismgr = get_ipython().history_manager   

2)获取会话ID:

session_id = hismgr.get_last_session_id()

3)删除历史记录行 line_id (假设这里是111)和 session_id

hismgr.db.execute('DELETE FROM history WHERE line={0} and session={1}'.format(111, session_id))

4) In 和 Out 数组列表也类似于历史记录,但它存储在内存中,因此可以像变量一样进行扫描或重写。

In[111]=Out[111]=''

要“阻止命令保存到ipython历史记录”,意味着删除该行 历史 记录在数据库中并重写  和 退房 在ipython环境中的数组。我们可以将这四条线合并为一条,为所有人做一次工作。 这是一个例子 如果我们要删除第128行:

In [127]: history -l 3 -n
 124: history -l 3 -n
 125: hismgr = get_ipython().history_manager; session_id = hismgr.get_last_session_id();hismgr.db.execute('DELETE FROM history WHERE line={0} and session={1}'.format(123, session_id))
 126: history -l 3 -n

In [128]: passwd='123456'

In [129]: hismgr = get_ipython().history_manager; session_id = hismgr.get_last_session_id();hismgr.db.execute('DELETE FROM history WHERE line={0} and session={1}'.format(128, session_id));In[128]=Out[128]='';
Out[129]: <sqlite3.Cursor at 0x7f8dce3dae30>

In [130]: history -l 3 -n
 126: history -l 3 -n
 127: history -l 3 -n
 129: hismgr = get_ipython().history_manager; session_id = hismgr.get_last_session_id();hismgr.db.execute('DELETE FROM history WHERE line={0} and session={1}'.format(128, session_id));In[128]=Out[128]='';

历史记录第128行消失了。

这是我经历的一些文件

IPython.core.history.HistoryManager

蟒蛇-sqlite3的


7
2018-01-29 23:58



这并不是“避免在历史中存储一条线”,而是将其从历史后的事实中删除。 - ivan_pozdeev
@ivan_pozdeev我知道。但是我通读了ipython文档,并且找不到某种方法真的“阻止命令保存到历史记录中”,所以我说如果我删除该行就会做同样的工作。 - realhu