简体   繁体   English

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

[英]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有四列: sessionlinesourcesource_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) InOut 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 环境中重写InOut数组。 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

python-sqlite3 python-sqlite3

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.这是因为,正如您所看到的,当魔法命令获得控制时,当前输入已经被存储。

    • readline: there's no relevant entry in the public API, so it's implementation-specific. readline:公共 API 中没有相关条目,因此它是特定于实现的。 Eg for 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
    • Decorating 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_celladd_history应该可以解决问题。
  • automatically remove evidence input/output from history immediately after execution.执行后立即自动从历史记录中删除证据输入/输出。 This can be done with a prefix magic.这可以通过前缀魔法来完成。

    • IPython: HistoryManager doesn't have any facilities to remove entries (neither from DB nor from variables). IPython: 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的可选缓存(默认情况下禁用)。
    • readline: remove_history_item(index) is in the API. readline: 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()
  • storing it elsewhere (like a configuration file only readable by you)将其存储在其他地方(例如只能由您读取的配置文件)

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM