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

时间:2016-01-29 20:35:44

标签: python ipython history

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

3 个答案:

答案 0 :(得分:7)

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

ipython历史记录存储在$(ipython locate)/profile_default/history.sqlite中的 sqlite数据库文件中。

数据库表历史记录有四列:会话来源来源_raw < / strong>即可。 会话列显示当前会话的session_id,可以使用get_ipython().history_manager.hisdb.get_last_session_id()中的ipython: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)InOut数组列表也类似于历史记录,但它存储在内存中,因此可以像变量一样进行扫描或重写。

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

要阻止命令保存到ipython历史记录中,表示删除数据库中行的历史记录记录并重写 In Out 数组。我们可以将这四条线合并为一条,为所有人做一次工作。 以下是一个示例,如果我们要删除第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

python-sqlite3

答案 1 :(得分:4)

过时注意:这是为IPython 4.0.1编写的。 As of v5, IPython no longer uses readline

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

IPython中有两种历史记录:

  • readline历史记录。它有特殊键/组合键(上/下,Ctrl-R等)。仅存储在控制台上输入的行(带有<Enter>)(或者,在pyreadline中,也可以从剪贴板粘贴)。 IPython依赖于Python readline API的本地实现,它没有&#34;不添加&#34;功能,通常会将每一行添加到历史记录中 IPython有一个缓解这个的工具,IPython.core.interactiveshell.ReadlineNoRecord,一个上下文管理器,它创建历史快照然后恢复它。自ipython 4.0.1起,它仅由%run魔法使用,以避免将脚本互动输入添加到历史记录中。

  • IPython历史。它保存在DB和自动变量中。它包含完整的输入(readline分别抓取每个<Enter>&#39; ed for line for multiline one)和输出。保存在HistoryManager.store_inputs()(对于输入)和HistoryManager.store_output()(对于输出)中实现,该InteractiveShell.run_cellstore_history调用并由其TerminalInteractiveShell.interact参数控制。后者又从store_history=True pyreadline调用。

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

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

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

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

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

答案 2 :(得分:0)

我自己一直在寻找解决方案,然后意识到我可以input秘密。例如,我在使用 pygithub 时使用以下内容来初始化 github API:

In [1]: gh = github.Github(base_url="https://api.github.com", login_or_token=input("token: "))
token: abcd

In [2]: %hist
gh = github.Github(base_url="https://api.github.com", login_or_token=input("token: "))
%hist