![](/img/trans.png)
[英]Python tab-completion not working in interactive console (Ubuntu 20.04)
[英]How can I get tab-completion to work in gdb's Python-interactive (pi) shell?
通常,在 Python shell 中,我可以按兩次 Tab 來獲取提示列表。
另一方面,在 gdb 的 Python shell ( pi
或python-interactive
命令)中,只有 gdb 樣式的完成。
示例 session:
$ gdb -q
(gdb) pi
>>> gdb
<module 'gdb' from '/usr/share/gdb/python/gdb/__init__.py'>
>>> gdb.TabTab
>>> show TabTab
Display all 148 possibilities? (y or n)
ada exec-direction record
agent exec-done-display remote
annotate exec-file-mismatch remoteaddresssize
Python 自動完成至少應該是這樣的。
$ python
Python 3.
Type "help", "copyright", "credits" or "license" for more information.
>>> import sys
>>> sys.TabTab
sys.abiflags sys.hash_info
sys.addaudithook( sys.hexversion
sys.api_version sys.implementation
如何在 gdb 中獲得相同/相似的東西? 特別是帶有制表符完成的 IPython shell 很好。
失敗的嘗試:
import readline import rlcompleter readline.parse_and_bind("tab: complete")
當在 sys.tab 之后按下Tab時,使 shell output 成為文字選項卡sys.
或類似的。
至少它確實適用於標識符選項卡完成( a Tab Tab
確實列出了一些條目)
看起來這是因為與 gdb 的一些交互get_completer_delims
都會重置為某個值,如果運行上面的代碼,那么 gdb之外的選項卡完成也會切換到“Python 模式”。
使用background_zmq_ipython
會導致分段錯誤,因為無法從主線程外部讀取某些 gdb API(例如gdb.Value
)。
使用IPython.embed()
還可以使Tab output 成為文字制表符。
The official gdb documentation https://sourceware.org/gdb/current/onlinedocs/gdb/Completion.html doesn't mention anything about Python.
我想出了幾種方法。
我想不出任何方法來使用內置的readline
庫。 有關更多詳細信息,請參閱問題中的失敗嘗試。
重置標准輸出和標准錯誤。
import sys sys.stdout=sys.__stdout__ sys.stderr=sys.__stderr__ import IPython IPython.embed(colors="neutral")
記得在之后重置 stdout 和 stderr 以避免可能出現的問題。
參考:
當所有標准輸入、標准輸出和標准錯誤都是 tty 設備時,IPython 只會使用制表符補全和顏色。 默認情況下 gdb sys.stdout 和 sys.stderr 是 gdb 包裝器(這樣 gdb 可以在分頁時執行“按回車繼續”限制)
啟動一個kernel,單獨啟動一個控制台。
import IPython IPython.embed_kernel()
閱讀控制台 output 以了解如何連接,以及如何從遠程控制台退出終端。
使用我的其他答案,也可以以編程方式遠程退出終端。
啟動一個kernel(復雜方式)
閱讀IPython的源代碼,了解如何手動啟動一個kernel,並在此過程中獲取連接文件路徑。
import threading import subprocess import IPython from ipykernel.kernelapp import IPKernelApp import sys app = IPKernelApp.instance() app.initialize([]) app.kernel.user_module = sys.modules[__name__] app.kernel.user_ns = locals() app.shell.set_completer_frame() def console_thread_run(): subprocess.run(["jupyter-console", "--no-confirm-exit", "--existing", app.abs_connection_file ]) app.kernel.do_shutdown(restart=False) console_thread=threading.Thread(target=console_thread_run) console_thread.start() app.start()
使用background_zmq_ipython
啟動 kernel(訪問內部屬性,可能隨時中斷)。
主要區別在於sys.stdin
、 sys.stdout
等不受影響。 請參閱background_zmq_ipython
文檔和ipython - 為 Python 腳本提供遠程 shell - 堆棧內存溢出了解更多詳細信息。
import subprocess import logging import threading from background_zmq_ipython import IPythonBackgroundKernelWrapper kernel_wrapper = IPythonBackgroundKernelWrapper( banner="", # default value is "Hello from background-zmq-ipython." user_ns=globals(), logger=logging.Logger("IPython", level=logging.INFO) # no handler # otherwise it will print "To connect another client to this IPython kernel"... ) kernel_wrapper.thread=threading.main_thread() # workaround for assertions subprocess.Popen(["python", "-c", ( "from jupyter_console.app import ZMQTerminalIPythonApp;" "app = ZMQTerminalIPythonApp();" "app.initialize();" "app.shell.own_kernel=True;" "app.start();" ), "--no-confirm-exit", "--existing", kernel_wrapper.connection_filename ]) kernel_wrapper._thread_loop()
還展示了如何將消息“保持 kernel 活着”更改為“關閉內核”。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.