python:是否可以将控制台连接到正在运行的进程中

我只想看看进程的状态,是否可以将控制台附加到进程中,以便可以调用进程内的函数并查看一些全局variables。

这个过程最好不受影响(当然,性能可能会下降一点)

如果您有权访问该程序的源代码,则可以相对轻松地添加此function。

请参阅576515食谱 : Debugging a running python process by interrupting and providing an interactive prompt (Python)

去引用:

这提供了代码,允许任何使用它的python程序在当前点被中断,并通过普通的python交互式控制台进行通信。 这允许调查本地,全局和相关的程序状态,以及调用任意函数和类。

要使用,进程应该导入模块,并在启动过程中的任何时候调用listen()。 为了中断这个过程,脚本可以直接运行,给出进程的进程ID作为参数debugging。


rconsole提供了大致相同概念的另一个实现。 从文档:

rconsole是一个具有自动完成function的远程Python控制台,可用于检查和修改正在运行的脚本的命名空间。

要在脚本中调用,请执行以下操作:

 from rfoo.utils import rconsole rconsole.spawn_server() 

从一个shell附加做:

 $ rconsole 

安全说明:使用spawn_server()启动的rconsole监听器将接受任何本地连接,因此可能不安全以便在共享主机或类似环境中使用!

这会中断你的进程(除非你在一个线程中启动它),但是你可以使用code模块来启动一个Python控制台:

 import code code.interact() 

这将阻塞,直到用户通过执行exit()退出交互式控制台。

code模块至less可以在Python v2.6中使用,可能还有其他的。

我倾向于将这种方法与我的Linux工作(Windows版,见下文)结合使用。 我把它放在我的Python脚本的顶部:

 import code import signal signal.signal(signal.SIGUSR2, lambda sig, frame: code.interact()) 

然后从具有kill -SIGUSR2 <PID>的shell中触发它,其中<PID>是进程标识。 这个过程然后停止它正在做的事情,并呈现一个控制台:

 Python 2.6.2 (r262:71600, Oct 9 2009, 17:53:52) [GCC 3.4.2] on linux2 Type "help", "copyright", "credits" or "license" for more information. (InteractiveConsole) >>> 

一般从那里我将加载远程debugging器的服务器端组件,如优秀的WinPDB 。

Windows不是POSIX兼容的操作系统,因此不提供与Linux相同的信号。 但是, Python v2.2及更高版本公开了一个特定于Windows的信号SIGBREAK (通过按CTRL + Pause/Break触发)。 这不会干扰正常的CTRL + CSIGINT )操作,所以是一个方便的select。

因此,上面的便携式,但稍微丑陋的版本是:

 import code import signal signal.signal( vars(signal).get("SIGBREAK") or vars(signal).get("SIGUSR2"), lambda sig, frame: code.interact() ) 

这种方法的优点:

  • 没有外部模块(所有标准的Python东西)
  • 几乎不会消耗任何资源,直到触发(2次导入)

下面是我在生产环境中使用的代码,它将加载WinPDB的服务器端(如果有的话),然后回退到打开Python控制台。

 # Break into a Python console upon SIGUSR1 (Linux) or SIGBREAK (Windows: # CTRL+Pause/Break). To be included in all production code, just in case. def debug_signal_handler(signal, frame): del signal del frame try: import rpdb2 print print print "Starting embedded RPDB2 debugger. Password is 'foobar'" print print rpdb2.start_embedded_debugger("foobar", True, True) rpdb2.setbreak(depth=1) return except StandardError: pass try: import code code.interact() except StandardError as ex: print "%r, returning to normal program flow" % ex import signal try: signal.signal( vars(signal).get("SIGBREAK") or vars(signal).get("SIGUSR1"), debug_signal_handler ) except ValueError: # Typically: ValueError: signal only works in main thread pass 

使用pyrasite-shell 。 我不敢相信它的效果如此之好,但确实如此。 “ 给它一个pid,得到一个壳 ”。

 $ sudo pip install pyrasite $ echo 0 | sudo tee /proc/sys/kernel/yama/ptrace_scope # If YAMA activated, see below. $ pyrasite-shell 16262 Pyrasite Shell 2.0 Connected to 'python my_script.py' Python 2.7.6 (default, Jun 22 2015, 17:58:13) [GCC 4.8.2] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> globals() >>> print(db_session) >>> run_some_local_function() >>> some_existing_local_variable = 'new value' 

这启动了python shell,可以访问运行python进程的globals()和locals()variables以及其他奇妙的东西。

只在Ubuntu上亲自testing过,但似乎也迎合了OSX。

改编自这个答案 。

注意:closuresptrace_scope属性的行只对使用CONFIG_SECURITY_YAMA打开的内核/系统是必需的。 在敏感的环境中,要小心ptrace_scope,因为它可能会引入一些安全漏洞。 详情请看这里 。

为什么不简单地使用pdb模块? 它允许您停止脚本,检查元素值,并逐行执行代码。 而且由于它是build立在Python解释器之上的,它还提供了经典解释器提供的function。 要使用它,只需把这两行代码放在你想停止和检查的地方:

 import pdb pdb.set_trace() 

另外一种可能性,不用在python脚本中添加东西,这里描述:

https://wiki.python.org/moin/DebuggingWithGdb

不幸的是,这个解决scheme还需要一些深思熟虑,至less在你需要使用带有debugging符号的python版本的情况下。

使用PyCharm,我得到了连接到Ubuntu的进程失败。 修复这个是禁用YAMA。 欲了解更多信息,请参阅askubuntu

 echo 0 | sudo tee /proc/sys/kernel/yama/ptrace_scope