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

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

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

но в Python

argv[0] = "othername"

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

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

8 ответов


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

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

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

Если это так, вам нужно использовать интерфейс WMI Тима Голдена и позвонить .Измените метод на службе... на по крайней мере, согласно его учебник.

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

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


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

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

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


на самом деле вам нужно 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" после этого: (. Но!--7--> и ps -A покажет новое имя процесса "тестирование да":). Также killall и pkill будет работать с новыми имя.

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

обновление: решение, опубликованное в этом ответе, иногда не играет хорошо на FreeBSD. Теперь я использую пы-переноса функции setproctitle указано в ответ в течение года или около того на различных коробках linux и freebsd. Нет до сих пор не удается! И все должны! :). Он использует почти тот же код, что и PostgreSQL использует в своей основной базе данных и дочерних процессах.


посмотреть переноса функции setproctitle пакета

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


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

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

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

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

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

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


мой ответ на подобный вопрос помечен как дублировать:

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

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

#!/usr/bin/env python

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

#!/usr/bin/python

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


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


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

обратите внимание на один '=' знак