[英]how can I avoid storing a command in ipython history?
In bash I can prevent a command from being saved to bash history by putting a space in front of it.在 bash 中,我可以通过在命令前面放置一个空格来防止将命令保存到 bash 历史记录中。 I cannot use this method in ipython.
我不能在 ipython 中使用这种方法。 How would I do the equivalent in ipython?
我将如何在 ipython 中执行等效操作?
I think I finally figure this out.我想我终于弄清楚了。 This method not really 'prevent' the ipython to record history but actually delete the history record.
这种方法并没有真正“阻止”ipython 记录历史记录,而是实际上删除了历史记录。 But I think still it is a good way to achieve this goal.
但我认为这仍然是实现这一目标的好方法。
ipython history is stored in a sqlite database file in $(ipython locate)/profile_default/history.sqlite
. ipython 历史记录存储在
$(ipython locate)/profile_default/history.sqlite
中的sqlite 数据库文件中。
The database table History has four columns: session , line , source and source_raw .数据库表History有四列: session 、 line 、 source和source_raw 。 The session column presents for the
session_id
of current session, it can be get with the method in ipython: get_ipython().history_manager.hisdb.get_last_session_id()
in ipython
. session列显示当前会话的
session_id
,可以通过 ipython 中的get_ipython().history_manager.hisdb.get_last_session_id()
ipython
。 The line column is just the line num.该生产线列只是行号。
So what I'm going to do is I'm going to delete this record in the database within ipython
enviroment:所以我要做的是在
ipython
环境中删除数据库中的这条记录:
1) The history db object can be get using get_ipython().history_manager.db
in ipython
1) 可以在
ipython
使用get_ipython().history_manager.db
获取历史数据库对象
hismgr = get_ipython().history_manager
2) get the session id: 2)获取会话ID:
session_id = hismgr.get_last_session_id()
3) delete the history line with the line_id
(assume it is 111 here) and 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) the In
and Out
Array List is also kind like history, but it stored in memory, so it could be sweep or rewrite like variable. 4)
In
和Out
Array List 也有点像history,但它存储在内存中,所以它可以像变量一样被sweep或rewrite。
In[111]=Out[111]=''
To 'prevent a command from being saved to ipython history', means delete the line's history record in database and and rewrite In and Out Array in ipython enviroment. “防止命令被保存到 ipython 历史记录”,意味着删除该行在数据库中的历史记录,并在 ipython 环境中重写In和Out数组。 And we could combine these four lines into to one to do the job one time for all.
我们可以将这四行合二为一,一次性完成所有工作。 Here is an example if we want to delete line 128:
如果我们要删除第 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]='';
The history line 128 is gone.历史线 128 消失了。
Here is some documents I went through这是我浏览的一些文件
IPython.core.history.HistoryManager IPython.core.history.HistoryManager
Obsolescence note: this was written for IPython 4.0.1
.过时说明:这是为
IPython 4.0.1
编写的。 As of v5, IPython no longer uses readline
.从 v5 开始,IPython 不再使用
readline
。
No stock way, can be added in or worked around.没有库存方式,可以添加或解决。
There are two kinds of history in IPython: IPython中有两种历史:
readline
history. readline
历史。 It is available with special keys/key combinations (up/down, Ctrl-R etc).它可用于特殊键/组合键(向上/向下、Ctrl-R 等)。 Only stores lines entered (with
<Enter>
) on the console (or, in pyreadline
, pasted from the clipboard, too).只存储在控制台上输入(使用
<Enter>
)的行(或者,在pyreadline
,也从剪贴板粘贴)。 IPython relies on a local implementation of the Python readline
API which doesn't have a "do not add" function and normally adds every line to history. IPython 依赖于Python
readline
API的本地实现,它没有“不添加”功能,通常会将每一行添加到历史记录中。
IPython has a facility to alleviate this, IPython.core.interactiveshell.ReadlineNoRecord
, a context manager that makes a snapshot of history then restores it. IPython 有一个工具来缓解这个问题,
IPython.core.interactiveshell.ReadlineNoRecord
,一个上下文管理器,可以制作历史快照然后恢复它。 As of ipython 4.0.1
, it's only used by %run
magic to avoid adding script interactive input to history.从
ipython 4.0.1
,它仅被%run
magic 使用以避免将脚本交互式输入添加到历史记录中。
IPython history. IPython 历史。 It's saved in the DB and automatic variables.
它保存在数据库和自动变量中。 It contains complete inputs (
readline
grabs each <Enter>
'ed line separately for multiline ones) and outputs.它包含完整的输入(
readline
为多行分别抓取每个<Enter>
ed行)和输出。 Saving is implemented in HistoryManager.store_inputs()
(for inputs) and HistoryManager.store_output()
(for outputs) which is called from InteractiveShell.run_cell
and is governed by its store_history
argument.保存在
HistoryManager.store_inputs()
(用于输入)和HistoryManager.store_output()
(用于输出)中实现,它从InteractiveShell.run_cell
调用并由其store_history
参数控制。 The latter is in turn called from TerminalInteractiveShell.interact
with store_history=True
.后者又从
TerminalInteractiveShell.interact
调用,并带有store_history=True
。
There are two ways to solve the problem for either layer:有两种方法可以解决任一层的问题:
prevent adding the input in the first place.防止首先添加输入。 This cannot be done with a magic prefixed to a command, only with one that is run as a separate command and toggles a flag.
这不能通过命令前缀的魔法来完成,只能使用作为单独命令运行并切换标志的命令。 That's because, as you've seen, the current input has already been stored by the time a magic command gets control.
这是因为,正如您所看到的,当魔法命令获得控制时,当前输入已经被存储。
pyreadline
, adding is done with pyreadline.modes.basemode.BaseMode.add_history()
.pyreadline
,添加是使用pyreadline.modes.basemode.BaseMode.add_history()
。 The mode object is accessible as get_ipython().readline.rl.mode
.get_ipython().readline.rl.mode
。run_cell
and add_history
with wrappers checking flags in corresponding objects and a custom magic command that sets/toggles them should do the trick.run_cell
和add_history
应该可以解决问题。 automatically remove evidence input/output from history immediately after execution.执行后立即自动从历史记录中删除
证据输入/输出。 This can be done with a prefix magic.这可以通过前缀魔法来完成。
HistoryManager
doesn't have any facilities to remove entries (neither from DB nor from variables). HistoryManager
没有任何删除条目的工具(既不是从数据库中也不是从变量中)。 Alas, hacking the DB by hand/replacing stock HistoryManager
is necessary.HistoryManager
是必要的。 Also note that the class has an optional cache of HistoryManager.db_cache_size
(disabled by default).HistoryManager.db_cache_size
的可选缓存(默认情况下禁用)。remove_history_item(index)
is in the API. remove_history_item(index)
在 API 中。 You need to know the number of lines in the input. Alternatively, if you only require this to enter passwords, consider other ways that don't echo the password on screen (thus not making it a part of console history):或者,如果您只需要输入密码,请考虑其他不会在屏幕上回显密码的方法(因此不会使其成为控制台历史记录的一部分):
getpass.getpass()
I was looking for a solution myself and then realized that I could just input
the secret.我自己正在寻找解决方案,然后意识到我可以
input
秘密。 Eg, I used the below to initialize github API when using pygithub:例如,我在使用 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
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.