簡體   English   中英

如何避免在 ipython 歷史記錄中存儲命令?

[英]how can I avoid storing a command in ipython history?

在 bash 中,我可以通過在命令前面放置一個空格來防止將命令保存到 bash 歷史記錄中。 我不能在 ipython 中使用這種方法。 我將如何在 ipython 中執行等效操作?

我想我終於弄清楚了。 這種方法並沒有真正“阻止”ipython 記錄歷史記錄,而是實際上刪除了歷史記錄。 但我認為這仍然是實現這一目標的好方法。

ipython 歷史記錄存儲在$(ipython locate)/profile_default/history.sqlite中的sqlite 數據庫文件中。

數據庫表History有四列: sessionlinesourcesource_raw session列顯示當前會話的session_id ,可以通過 ipython 中的get_ipython().history_manager.hisdb.get_last_session_id() ipython 生產線列只是行號。

所以我要做的是在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) InOut Array List 也有點像history,但它存儲在內存中,所以它可以像變量一樣被sweep或rewrite。

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

“防止命令被保存到 ipython 歷史記錄”,意味着刪除該行在數據庫中的歷史記錄,並在 ipython 環境中重寫InOut數組。 我們可以將這四行合二為一,一次性完成所有工作。 如果我們要刪除第 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

過時說明:這是為IPython 4.0.1編寫的。 從 v5 開始,IPython 不再使用readline


沒有庫存方式,可以添加或解決。

IPython中有兩種歷史:

  • readline歷史。 它可用於特殊鍵/組合鍵(向上/向下、Ctrl-R 等)。 只存儲在控制台上輸入(使用<Enter> )的行(或者,在pyreadline ,也從剪貼板粘貼)。 IPython 依賴於Python readline API的本地實現,它沒有“不添加”功能,通常會將每一行添加到歷史記錄中。
    IPython 有一個工具來緩解這個問題, IPython.core.interactiveshell.ReadlineNoRecord ,一個上下文管理器,可以制作歷史快照然后恢復它。 ipython 4.0.1 ,它僅被%run magic 使用以避免將腳本交互式輸入添加到歷史記錄中。

  • IPython 歷史。 它保存在數據庫和自動變量中。 它包含完整的輸入( readline為多行分別抓取每個<Enter> ed行)和輸出。 保存在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_celladd_history應該可以解決問題。
  • 執行后立即自動從歷史記錄中刪除證據輸入/輸出。 這可以通過前綴魔法來完成。

    • IPython: HistoryManager沒有任何刪除條目的工具(既不是從數據庫中也不是從變量中)。 唉,手動破解數據庫/替換庫存HistoryManager是必要的。 另請注意,該類具有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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM