python: можно ли подключить консоль к запущенному процессу
Я просто хочу увидеть состояние процесса, можно ли подключить консоль в процесс, чтобы я мог вызывать функции внутри процесса и видеть некоторые глобальные переменные.
лучше процесс работает без ущерба (конечно, производительность может немного снизиться)
6 ответов:
Если у вас есть доступ к исходному коду программы, вы можете добавить эту функциональность относительно легко.
посмотреть рецепт 576515:
Debugging a running python process by interrupting and providing an interactive prompt (Python)
цитата:
Это обеспечивает код, чтобы позволить любой python программа, которая использует его, чтобы быть прервано в текущей точке, и общался с помощью обычного python интерактивная консоль. Это позволяет локальные, глобальные и связанные с ними программы государство, подлежащее расследованию, а также вызов произвольных функций и занятия.
использовать, процесс должен импортировать модуль и вызов listen() в любой момент во время запуска. Чтобы прервать это процесс, скрипт можно запустить непосредственно, давая идентификатор процесса процесс отладки в качестве параметра.
другая реализация примерно той же концепции обеспечивается rconsole. Из документации:
rconsole дистанционное Консоль Python с автоматическим завершением, которое может быть используется для проверки и изменения пространство имен скрипта.
чтобы вызвать в скрипте do:
from rfoo.utils import rconsole rconsole.spawn_server()
чтобы прикрепить из оболочки делают:
$ rconsole
примечание по безопасности: слушатель rconsole начато с spawn_server () будет примите любое локальное соединение и может поэтому небезопасно использовать в общем доступе хостинг или аналогичные среды!
это прервет ваш процесс (если вы не запустите его в потоке), но вы можете использовать
code
модуль для запуска консоли Python:import code code.interact()
это будет блокироваться до тех пор, пока пользователь не выйдет из интерактивной консоли, выполнив
exit()
.The
code
модуль доступен в, по крайней мере, в Python версии 2.6, наверное, другим.я склонен использовать этот подход в сочетании с сигналами для моей работы в Linux (для Windows, см. ниже). Я хлопаю это в верхней части моего Скрипты Python:
import code import signal signal.signal(signal.SIGUSR2, lambda sig, frame: code.interact())
а затем вызвать его из оболочки с
kill -SIGUSR2 <PID>
, где<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) >>>
обычно оттуда я загружаю серверный компонент удаленного отладчика, как отличный WinPDB.
Windows не является POSIX-совместимая ОС, и поэтому не обеспечивает те же сигналы, что и Linux. Однако,Python v2. 2 и выше выставляют специфичный для Windows сигнал
SIGBREAK
(запускается клавишейCTRL
+Pause/Break
). Это делает не мешают нормальноCTRL
+C
(SIGINT
) деятельность, и так сподручная альтернатива.поэтому портативный, но немного уродливый, версия выше:
import code import signal signal.signal( vars(signal).get("SIGBREAK") or vars(signal).get("SIGUSR2"), lambda sig, frame: code.interact() )
преимущества такого подхода:
- нет внешних модулей (все стандартные Python вещи)
- почти не потребляет ресурсы до срабатывания (2x импорт)
вот код, который я использую в своей рабочей среде, который загрузит серверную часть 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
использовать пиразит-оболочка. Я не могу поверить, что это работает так хорошо, но это так. "дайте ему пид, получите оболочку".
$ 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 с доступом к переменным globals() и locals() этого запущенного процесса python и другим замечательным вещам.
только тестировал это лично на Ubuntu, но, похоже, тоже обслуживает OSX.
адаптировано из ответ.
Примечание: переключение линии прочь
ptrace_scope
свойство необходимо только для ядер / систем, которые были построены сCONFIG_SECURITY_YAMA
далее. Будьте осторожны, возясь с ptrace_scope в чувствительных средах, потому что это может привести к определенным уязвимостям безопасности. Смотрите здесь для сведения.
почему бы просто не использовать pdb модуль? Он позволяет остановить скрипт, проверить значения элементов и выполнить код строка за строкой. И поскольку он построен на интерпретаторе Python, он также предоставляет функции, предоставляемые классическим интерпретатором. Чтобы использовать его, просто поместите эти 2 строки в свой код, где вы хотите остановиться и проверить его:
import pdb pdb.set_trace()
другая возможность, без добавления материала в Скрипты python, описана здесь:
https://wiki.python.org/moin/DebuggingWithGdb
к сожалению, это решение также требует некоторой предусмотрительности, по крайней мере, в той степени, в которой вам нужно использовать версию python с отладочными символами в ней.
используя PyCharm, я получал сбой подключения к процессу в Ubuntu. Исправление для этого-отключить YAMA. Для получения дополнительной информации см. askubuntu
echo 0 | sudo tee /proc/sys/kernel/yama/ptrace_scope