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
+ C
( SIGINT
)操作,所以是一个方便的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