如何避免将命令存储在 ipython 历史记录中?
how can I avoid storing a command in ipython history?
在 bash 中,我可以通过在命令前面放置 space 来防止将命令保存到 bash 历史记录中。我无法在 ipython 中使用此方法。我将如何做 ipython 中的等价物?
我想我终于弄明白了。这个方法不是真正'prevent'ipython记录历史而是删除历史记录。但我认为这仍然是实现这一目标的好方法。
ipython 历史存储在 $(ipython locate)/profile_default/history.sqlite
的 sqlite 数据库 文件中。
数据库table 历史有四列:session, line , 来源 和 source_raw。 session列代表当前session的session_id
,可以通过ipython中的方法获取:get_ipython().history_manager.hisdb.get_last_session_id()
in ipython
. line 列只是行号。
所以我要做的是删除数据库中ipython
环境中的这条记录:
1) 历史数据库对象可以在ipython
中使用get_ipython().history_manager.db
获取
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
Array List 也有点像历史,但它存储在内存中,所以它可以像变量一样被清除或重写。
In[111]=Out[111]=''
到'prevent a command from being saved to ipython history',表示删除数据库中该行的历史记录,并重写In和 ipython 环境中的 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 4.0.1
编写的。 As of v5, IPython no longer uses readline
.
没有库存方式,可以添加或变通。
IPython有两种历史:
readline
历史。它可用于特殊的 keys/key 组合(up/down、Ctrl-R 等)。仅存储在控制台上输入(使用 <Enter>
)的行(或者,在 pyreadline
中,也从剪贴板粘贴)。 IPython 依赖于 Python readline
API 的本地实现,它没有 "do not add" 函数,通常会将每一行添加到历史记录中。
IPython 有一个工具可以缓解这个问题,IPython.core.interactiveshell.ReadlineNoRecord
,一个创建历史快照然后恢复它的上下文管理器。从 ipython 4.0.1
开始,它仅被 %run
魔术使用,以避免将脚本交互输入添加到历史记录中。
IPython 历史。它保存在数据库和自动变量中。它包含完整的输入(readline
为多行分别抓取每个 <Enter>
的行)和输出。保存在 HistoryManager.store_inputs()
(对于输入)和 HistoryManager.store_output()
(对于输出)中实现,它们从 InteractiveShell.run_cell
调用并由其 store_history
参数控制。后者依次从 TerminalInteractiveShell.interact
和 store_history=True
.
调用
有两种方法可以解决任一层的问题:
首先阻止添加输入。这不能用命令前缀的魔法来完成,只能用 运行 作为单独的命令并切换标志。那是因为,如您所见,当前输入在魔术命令获得控制权时已经存储。
- readline:public API 中没有相关条目,因此它是特定于实现的。例如。对于
pyreadline
,添加是用 pyreadline.modes.basemode.BaseMode.add_history()
完成的。模式对象可以作为 get_ipython().readline.rl.mode
. 访问
- 装饰
run_cell
和 add_history
使用包装器检查相应对象中的标志和 custom magic command sets/toggles 它们应该可以解决问题。
执行后立即从历史记录中自动删除 证据 input/output。这可以通过前缀魔法来完成。
- IPython:
HistoryManager
没有任何删除条目的工具(无论是从数据库还是从变量)。 las,通过 hand/replacing stock HistoryManager
破解数据库是必要的。另请注意,class 有一个可选的 HistoryManager.db_cache_size
缓存(默认情况下禁用)。
- readline:
remove_history_item(index)
在 API 中。您需要知道输入中的行数。
或者,如果您只需要它来输入密码,请考虑其他不会在屏幕上回显密码的方法(因此不会使其成为控制台历史记录的一部分):
getpass.getpass()
- 将其存储在别处(比如只有您可读的配置文件)
我自己正在寻找解决方案,然后意识到我可以 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
在 bash 中,我可以通过在命令前面放置 space 来防止将命令保存到 bash 历史记录中。我无法在 ipython 中使用此方法。我将如何做 ipython 中的等价物?
我想我终于弄明白了。这个方法不是真正'prevent'ipython记录历史而是删除历史记录。但我认为这仍然是实现这一目标的好方法。
ipython 历史存储在 $(ipython locate)/profile_default/history.sqlite
的 sqlite 数据库 文件中。
数据库table 历史有四列:session, line , 来源 和 source_raw。 session列代表当前session的session_id
,可以通过ipython中的方法获取:get_ipython().history_manager.hisdb.get_last_session_id()
in ipython
. line 列只是行号。
所以我要做的是删除数据库中ipython
环境中的这条记录:
1) 历史数据库对象可以在ipython
get_ipython().history_manager.db
获取
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
Array List 也有点像历史,但它存储在内存中,所以它可以像变量一样被清除或重写。
In[111]=Out[111]=''
到'prevent a command from being saved to ipython history',表示删除数据库中该行的历史记录,并重写In和 ipython 环境中的 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 4.0.1
编写的。 As of v5, IPython no longer uses readline
.
没有库存方式,可以添加或变通。
IPython有两种历史:
readline
历史。它可用于特殊的 keys/key 组合(up/down、Ctrl-R 等)。仅存储在控制台上输入(使用<Enter>
)的行(或者,在pyreadline
中,也从剪贴板粘贴)。 IPython 依赖于 Pythonreadline
API 的本地实现,它没有 "do not add" 函数,通常会将每一行添加到历史记录中。
IPython 有一个工具可以缓解这个问题,IPython.core.interactiveshell.ReadlineNoRecord
,一个创建历史快照然后恢复它的上下文管理器。从ipython 4.0.1
开始,它仅被%run
魔术使用,以避免将脚本交互输入添加到历史记录中。IPython 历史。它保存在数据库和自动变量中。它包含完整的输入(
readline
为多行分别抓取每个<Enter>
的行)和输出。保存在HistoryManager.store_inputs()
(对于输入)和HistoryManager.store_output()
(对于输出)中实现,它们从InteractiveShell.run_cell
调用并由其store_history
参数控制。后者依次从TerminalInteractiveShell.interact
和store_history=True
. 调用
有两种方法可以解决任一层的问题:
首先阻止添加输入。这不能用命令前缀的魔法来完成,只能用 运行 作为单独的命令并切换标志。那是因为,如您所见,当前输入在魔术命令获得控制权时已经存储。
- readline:public API 中没有相关条目,因此它是特定于实现的。例如。对于
pyreadline
,添加是用pyreadline.modes.basemode.BaseMode.add_history()
完成的。模式对象可以作为get_ipython().readline.rl.mode
. 访问
- 装饰
run_cell
和add_history
使用包装器检查相应对象中的标志和 custom magic command sets/toggles 它们应该可以解决问题。
- readline:public API 中没有相关条目,因此它是特定于实现的。例如。对于
执行后立即从历史记录中自动删除
证据input/output。这可以通过前缀魔法来完成。- IPython:
HistoryManager
没有任何删除条目的工具(无论是从数据库还是从变量)。 las,通过 hand/replacing stockHistoryManager
破解数据库是必要的。另请注意,class 有一个可选的HistoryManager.db_cache_size
缓存(默认情况下禁用)。 - readline:
remove_history_item(index)
在 API 中。您需要知道输入中的行数。
- IPython:
或者,如果您只需要它来输入密码,请考虑其他不会在屏幕上回显密码的方法(因此不会使其成为控制台历史记录的一部分):
getpass.getpass()
- 将其存储在别处(比如只有您可读的配置文件)
我自己正在寻找解决方案,然后意识到我可以 input
这个秘密。例如,我在使用 pygithub:
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