Есть ли способ изменить имя эффективного процесса в Python?

Можно ли изменить имя исполняемого процесса на Python script? Я хочу показать другое имя вместо реального имени процесса, когда я получу список системных процессов. В C я могу установить

strcpy(argv[0],"othername");

Но в Python

argv[0] = "othername"

похоже, не работает. Когда я получаю список процессов (с ps ax в моем linux box), настоящее имя не изменяется. Я предпочитаю портативное решение (или другое решение для posix и другое для оконных сред), если оно существует.

Заранее спасибо

Ответ 1

Проще говоря, нет портативного способа. Вам нужно будет проверить систему и использовать предпочтительный метод для этой системы.

Кроме того, я смущен тем, что вы подразумеваете под именами процессов в Windows.

Вы имеете в виду имя службы? Я так полагаю, потому что ничто иное не имеет никакого смысла (по крайней мере, для моего не-Windows, использующего мозг).

Если это так, вам нужно использовать Tim Golden WMI interface и вызвать метод .Change для службы... по крайней мере, согласно его tutorial.

Для Linux ни один из методов, которые я нашел, кроме этот плохо упакованный модуль, который устанавливает для вас argv [0].

Я даже не знаю, будет ли это работать на BSD-вариантах (у которых есть системный вызов setproctitle). Я уверен, что argv [0] не будет работать в Solaris.

Ответ 2

Недавно я написал модуль Python для изменения названия процесса переносимым способом: check https://github.com/dvarrazzo/py-setproctitle

Это оболочка вокруг кода, используемого PostgreSQL для выполнения изменения названия. В настоящее время он протестирован на Linux и Mac OS X: Windows (с ограниченной функциональностью) и порты BSD находятся в пути.

Изменить: по состоянию на июль 2010 года, модуль работает с BSD и имеет ограниченную функциональность в Windows и портирован на Python 3.x.

Ответ 3

на самом деле вам нужно 2 вещи в linux: измените argv[0] с C (для ps auxf и друзей) и вызовите prctl с флагом PR_SET_NAME.

Нет абсолютно никакого способа сделать первую часть из самого python. Хотя вы можете просто изменить имя процесса, вызвав prctl.

def set_proc_name(newname):
    from ctypes import cdll, byref, create_string_buffer
    libc = cdll.LoadLibrary('libc.so.6')
    buff = create_string_buffer(len(newname)+1)
    buff.value = newname
    libc.prctl(15, byref(buff), 0, 0, 0)

def get_proc_name():
    from ctypes import cdll, byref, create_string_buffer
    libc = cdll.LoadLibrary('libc.so.6')
    buff = create_string_buffer(128)
    # 16 == PR_GET_NAME from <linux/prctl.h>
    libc.prctl(16, byref(buff), 0, 0, 0)
    return buff.value

import sys
# sys.argv[0] == 'python'

# outputs 'python'
get_proc_name()

set_proc_name('testing yeah')

# outputs 'testing yeah'
get_proc_name()

ps auxf будет показывать только "python" после этого:( Но top и ps -A покажут новое имя процесса "тестирование да":). Также killall и pkill будут работать с новым именем.

btw, procname из googlecode также изменяет argv[0], таким образом, даже, изменяет вывод ps auxf.

UPDATE. Решение, размещенное в этом ответе, иногда не играет в FreeBSD. Я теперь использую py-setproctitle, указанный в этом ответе за год или так и на разных linux и freebsd. Пока не сработало! Всем тоже нужно!:). Он использует почти тот же код, что и PostgreSQL использует в его основной базе данных и дочерних процессах.

Ответ 4

Во-первых, я не уверен, что просто настройки argv[0] в программе на C изменят название, отображаемое в ps. Возможно, это происходит в некоторых unixen, но я понимаю, что этого не ожидается.

Во-вторых, поскольку Windows специально не совместима с POSIX, только несколько вещей "переносимы" между POSIX и не-POSIX. Поскольку вы конкретно говорите "ps", я предполагаю, что POSIX является вашим приоритетом, и Windows может не работать.

Что еще более важно, мое понимание изменения argv[0] заключается в том, что для выполнения этих изменений требуется вызов exec. В частности, вызов exec имеет как путь к исполняемому файлу, так и отдельный список argv. Создание собственного вызова позволяет вам разорвать соглашение оболочки о посылке исполняемого имени в argv[0].

У вас управление процессами библиотеки ОС, которое дает вам прямой доступ к библиотеке ОС для этого. Вы должны рассмотреть возможность взлома script на две части - стартер и "настоящую работу". Стартер устанавливает среду выполнения и выполняет реальную работу с требуемыми параметрами.

В C вы заменяете свой собственный процесс другим. В Python вы заменяете старый интерпретатор Python новым, у которого есть другой argv [0]. Надеюсь, на этом не будет. Некоторые программы проверяют argv [0], чтобы решить, что они делают.

У вас также есть subprocess.popen, который вы можете использовать для установки желаемых аргументов и исполняемых файлов. В этом случае, однако, родительский процесс должен задерживаться, чтобы собрать ребенка, когда ребенок закончит. Родитель может не делать ничего больше, чем Popen.wait

Ответ 5

Посмотрите setproctitle package

Это довольно портативная версия и работает на многих платформах.

Ответ 6

Мой ответ на аналогичный вопрос помечен как duplicate:

Проще (вам не нужно импортировать какие-либо библиотеки), но, возможно, не так элегантно. Вы не должны использовать "env" внутри линии shebang.

Другими словами, это будет называться "python" в списке процессов:

#!/usr/bin/env python

Но это будет указано с вашим именем сценария:

#!/usr/bin/python

Итак, вы сможете найти его с чем-то вроде pidof -x scriptname или ps -C scriptname

Ответ 7

Я нашел python-prctl, чтобы отлично работать под Linux. Вам нужно будет найти что-то еще для Windows.

Ответ 8

In [1]: import sys

In [2]: print sys.argv[0]
C:\Python25\scripts\ipython.py

In [3]: sys.argv[0] = 'foo'

In [4]: print sys.argv[0]
foo

Обратите внимание на одиночный знак "="